2017-10-07 116 views
3

我需要使用Apollo客戶端和React完成一個項目(貨幣兌換應用程序)。我需要用graphql包裝現有的REST api(fixer.io)。到目前爲止沒有運氣在網上尋找解決方案嘗試了幾個教程,但他們似乎並沒有工作。任何人都有這方面的經驗?使用Apollo React使用GraphQL包裝RESTapi

謝謝。

回答

2

使用Graphcool Framework,您可以定義resolver functions,它允許您輕鬆地包裝任何REST API。您可以定義一個函數並將其連接到GraphQL模式中的特定變異或查詢。我準備了a demo, wrapping the fixer API

嘗試運行此查詢來獲取匯率以美元爲基礎,例如:

query { 
    fixer(
    base: "USD" 
) { 
    base 
    date 
    eur 
    usd 
    rub 
    } 
} 

您可以建立這個演示自己是這樣的:

git clone [email protected]:graphcool/templates.git 
cd templates/curated/misc/fixer-wrapper 
npm install -g [email protected] 
graphcool init 
graphcool deploy 
graphcool playground 

請隨時分享您可能想到的任何改進,例如open source。你可以閱讀更多關於解析器here

+1

你也可以參考下面這個例子:https://github.com/graphcool/graphcool/tree/master/examples/rest-wrapper – nburk

0

我假設你使用Apollo client 2.0,並希望一切都是客戶端。

首先你需要一個apollo bridge link。它用於「當你還沒有GraphQL服務器並且想在客戶端上使用GraphQL」時。它的源代碼是很短,所以你可以內嵌它:

/* 
    Copyright (c) 2017 David Cizek 
    https://github.com/dacz/apollo-bridge-link 
*/ 
import { GraphQLSchema, graphql, print } from 'graphql'; 
import { addMockFunctionsToSchema, makeExecutableSchema } from 'graphql-tools'; 

import { ApolloLink } from 'apollo-link'; 
import Observable from 'zen-observable'; 

export const createBridgeLink = ({ schema, resolvers, mock, context = {} }) => { 
    let executableSchema; 
    if (typeof schema === 'string') { 
     executableSchema = makeExecutableSchema({ typeDefs: schema, resolvers }); 
    } else if (schema.kind === 'Document') { 
     executableSchema = makeExecutableSchema({ 
      typeDefs: print(schema), 
      resolvers, 
     }); 
    } else if (schema instanceof GraphQLSchema) { 
     executableSchema = schema; 
    } else { 
     throw new Error('schema should be plain text, parsed schema or executable schema.'); 
    } 

    if (mock) 
     {addMockFunctionsToSchema({ 
      schema: executableSchema, 
      preserveResolvers: true, 
     });} 

    return new ApolloLink(
     operation => 
      new Observable(observer => { 
       const { headers, credentials } = operation.getContext(); 
       const ctx = { 
        ...context, 
        headers, 
        credentials, 
       }; 

       graphql(executableSchema, print(operation.query), undefined, ctx, operation.variables, operation.operationName) 
        .then(data => { 
         observer.next(data); 
         observer.complete(); 
        }) 
        .catch(err => { 
         /* istanbul ignore next */ 
         observer.error(err); 
        }); 
      }), 
    ); 
}; 

export class BridgeLink extends ApolloLink { 
    requester; 

    constructor(opts) { 
     super(); 
     this.requester = createBridgeLink(opts).request; 
    } 

    request(op) { 
     return this.requester(op); 
    } 
} 

接下來創建模式和解析器:

// schema.js 
export default ` 
type Rate { 
    date: Date! 
    rate: Float! 
} 

type Query { 
    latestRate(from: String!, to: String!): Rate 
} 

schema { 
    query: Query 
} 
`; 


// resolvers.js 
const resolvers = { 
    Query: { 
    latestRate(obj, args, context, info) { 
     return fetch(`https://api.fixer.io/latest?base=${args.from}`).then(res => res.json()) 
     .then(res => { date: res.date, rate: res.rates[args.to] }) 
    } 
    } 
} 

export default resolvers; 

最後,創建一個阿波羅客戶工廠:

// clientFactory.js 
import { ApolloClient } from 'apollo-client'; 
import { InMemoryCache } from 'apollo-cache-inmemory'; 

import { BridgeLink } from './apollo-bridge-link'; 

import schema from './schema'; 
import resolvers from './resolvers'; 

export default() => { 
    const mock = false; 
    const context = {}; 

    const client = new ApolloClient({ 
     link: new BridgeLink({ schema, resolvers, mock, context }), 
     cache: new InMemoryCache(), 
    }); 
    return client; 
}; 

以下是你如何使用它:

import gql from 'graphql-tag'; 
import clientFactory from './clientFactory' 

const client = clientFactory(); 

client.query(gql`query { 
    latestRate(from: "USD", to: "EUR") { date, rate } 
}`).then(console.log) 

如果你想在使用它陣營:

import { ApolloProvider } from 'react-apollo'; 
const client = clientFactory(); 

const App = ({ data: { latestRate, refetch } }) => { 
    return <div> 
    <span>Today:</span><span>{latestRate.date}</span> 
    <span>1 USD equals:</span><span>{latestRate.rate} EUR</span> 
    <button onClick={() => refetch()}> 
     Refresh 
    </button> 
    </div> 
} 

const AppWithQuery = graphql(gql` 
    query { 
    latestRate(from: "USD", to: "EUR") { date, rate } 
    } 
`)(App); 

ReactDOM.render(
    <ApolloProvider client={client}> 
    <AppWithQuery/> 
    </ApolloProvider>, 
    document.getElementById('root'), 
); 
相關問題