2017-10-07 6 views
3

Ich brauche ein Projekt (Währung Exchange App) mit Apollo Client und React. Ich muss eine vorhandene REST-API (fixer.io) mit graphql umschließen. Bisher kein Glück, online eine Lösung zu finden. Habe mehrere Tutorials versucht, aber sie scheinen nicht zu funktionieren. Hat jemand Erfahrung damit?Wrapping einer RESTapi mit GraphQL mit Apollo React

Danke.

Antwort

2

Mit der Graphcool Framework können Sie resolver functions definieren, mit denen Sie problemlos jede REST-API umbrechen können. Sie können eine Funktion definieren und sie mit einer bestimmten Mutation oder Abfrage in Ihrem GraphQL-Schema verbinden.

Ich bereitete a demo, wrapping the fixer API vor.

Diese Abfrage ausführen, um die Wechselkurse mit USD als Basis zu erhalten, zum Beispiel:

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

Sie können dies selbst wie diese Demo bauen:

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

Bitte fühlen Sie sich frei zu teilen jede Verbesserung, die Sie vielleicht im Sinn haben, ist das Beispiel open source. Sie können mehr über Resolver here lesen.

+1

Sie auch auf dieses Beispiel beziehen: https://github.com/graphcool/graphcool/tree/master/examples/rest-wrapper – nburk

0

Ich nehme an, Sie verwenden Apollo client 2.0 und wollen alles auf der Clientseite sein.

Zuerst benötigen Sie eine apollo bridge link. Es wird verwendet "Wenn Sie noch keinen GraphQL-Server haben und GraphQL auf dem Client verwenden möchten". Sein Quellcode ist recht kurz, so dass Sie es inline können:

/* 
    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); 
    } 
} 

Nächstes erstellen Sie Schema und Resolvern:

// 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; 

Schließlich Sie ein apollo Client-Werk erstellen:

// 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; 
}; 

Hier ist, wie Sie es verwenden:

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) 

Wenn Sie es in verwenden möchten Reagieren:

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'), 
); 
Verwandte Themen