2017-12-01 4 views
0

Anpassung am Beispiel von GraphQL Best Practices durch das Apollo-Team erstellt (https://github.com/apollographql/GitHunt-API/tree/master/api), ich habe harte Zeit mit einem Resolver zu entwickeln, die in einer Liste von Person mit DataLoaders führen würden .GraphQL Resolver mit Dataloader und verschachtelten Endpunkten

Hier ist ein Beispiel für die api (Daten von: https://github.com/steveluscher/zero-to-graphql/tree/master/zero-node):

{ 
    "people": [ 
    { 
     "username": "steveluscher", 
     "id": "1", 
    }, 
    { 
     "username": "aholovaty", 
     "id": "2", 
    }, 
    { 
     "username": "swillison", 
     "id": "3", 
    }, 
    { 
     "username": "gvr", 
     "id": "4", 
    } 
    ] 
} 

Und eine Person vom Endpunkt /Leute

die Ausgabe von /people/ Endpunkt wie Gegeben/1/

{ 
    "person": { 
    "last_name": "Luscher", 
    "username": "steveluscher", 
    "friends": [ 
     "/people/2/", 
     "/people/3/" 
    ], 
    "id": "1", 
    "email": "[email protected]", 
    "first_name": "Steven" 
} 

Ich möchte einen Resolver haben, was mir eine Liste von Person geben würde wie:

[ 
    { 
    "person": { 
     "last_name": "Luscher", 
     "username": "steveluscher", 
     "friends": [ 
     "/people/2/", 
     "/people/3/" 
     ], 
     "id": "1", 
     "email": "[email protected]", 
     "first_name": "Steven" 
    } 
    }, 
    { 
    "person": { 
     "last_name": "Holovaty", 
     "username": "aholovaty", 
     "friends": [ 
     "/people/1/", 
     "/people/4/" 
     ], 
     "id": "2", 
     "email": "[email protected]", 
     "first_name": "Adrian" 
    } 
    }, 
    ... 
] 

Das ist, was ich bisher habe:

server.js

import { ApiConnector } from './api/connector'; 
import { People } from './api/models'; 

import schema from './schema'; 

export function run() { 
    const PORT = 3000; 

    const app = express(); 

    app.use(bodyParser.json()); 

    app.use('/graphql', graphqlExpress((req) => { 
     const query = req.query.query || req.body.query; 

     if (query && query.length > 2000) { 
      throw new Error('Query too large.'); 
     } 

     const apiConnector = new ApiConnector(); 

     return { 
      schema, 
      context: { 
       People: new People({ connector: apiConnector }), 
      }, 
     }; 
    })); 

    app.use('/graphiql', graphiqlExpress({ 
     endpointURL: '/graphql', 
    })); 

    const server = createServer(app); 

    server.listen(PORT,() => { 
     console.log(`API Server is now running on http://localhost:${PORT}`); 
    }); 

    return server; 
} 

models.js

connector.js

const API_ROOT = 'http://localhost:8080'; 

export class ApiConnector { 

    constructor() { 
     this.rp = rp; 

     this.loader = new DataLoader(this.fetch.bind(this)); 
    } 

    fetch(urls) { 
     const options = { 
      json: true, 
      resolveWithFullResponse: true, 
      headers: { 
       'user-agent': 'Request-Promise', 
      }, 
     }; 
     return Promise.all(urls.map((url) => { 
      return new Promise((resolve) => { 
       this.rp({ 
        uri: url, 
        ...options, 
       }).then((response) => { 
        const body = response.body; 
        resolve(body); 
       }).catch((err) => { 
        console.error(err); 
        resolve(null); 
       }); 
      }); 
     })); 
    } 

    get(path) { 
     return this.loader.load(API_ROOT + path); 
} 

Und der Resolver im Schema würde wie etwas haben:

const rootResolvers = { 
    Query: { 
     people(root, args, context) { 
      return context.People.getPeople(); 
     }, 
     person(root, { id }, context) { 
      return context.People.getPerson(id) 
     } 
    }, 
}; 

Bis jetzt kann ich die ersten Endpunkt/Leute/und eine Person aus/Menschen/ID /. Aber wie man es ändert, um eine Liste der Person zu haben? Ich bin mir nicht ganz sicher, wie/wo dieser Code sein sollte.

Vielen Dank!

Antwort

0

Sie könnten Ihre Leute Resolver brüllen wie der Code, um etwas ändern:

const rootResolvers = { 
    Query: { 
     people(root, args, context) {   
      const list = context.People.getPeople(); 

      if (list && list.length > 0) { 
       return list.map(item => context.People.getPerson(item.id)) 
      } 
     }, 
     ... 
    }, 
}; 

Ps: Sie sagten, dass Sie dataloader verwenden, so denke ich, Ihre API-Aufrufe nur zwischengespeichert wird, aber wenn es nicht ist In diesem Fall müssen Sie einen Cache implementieren, um zu vermeiden, dass Sie dieselben Endpunkte oft aufrufen.

Verwandte Themen