UNPKG

2.69 kBMarkdownView Raw
1# A neat GraphQL server in JavaScript
2
3MVP for a GraphQL server that makes the developers' life easier.
4
5This GraphQL server is built on
6* graphql-js
7
8## How to use:
9
10Apollo-server takes three inputs:
11
121. A GraphQL schema in shorthand format
131. One or more javascript code files that defines resolve functions
141. One or more javascript code files that define data loaders
15
16An example of a valid GraphQL shorthand input:
17```
18type Book {
19 id: ID!
20 title: String!
21 genre: Genre
22 author: Author
23}
24
25interface Person {
26 firstName: String!
27 lastName: String
28 middleName: String
29}
30
31type Author: Person {
32 id: ID!
33 firstName: String!
34 lastName: String
35 middleName: String
36 booksPublished: [Book]
37}
38
39enum Genre {
40 FICTION
41 NONFICTION
42}
43
44type RootQuery {
45 author(id: ID!): Author,
46 book(title: String!): Book
47}
48
49type RootMutation {
50 addBook(title: String!, genre: Genre!, author_id: ID): Book
51}
52```
53
54The corresponding file that defines how fields are resolved. If a field does not
55have a resolve function, it is assumed to be the standard resolve function.
56Resolve functions should be stateless.
57```
58const resolveFunctions = {
59 Book: {
60 author(book, _, ctx){ return ctx.loaders.author.get(book.author_id) },
61
62 // fields without resolve function just return book.<fieldName>
63 },
64
65 Author: {
66 booksPublished(author, _, _){ return ctx.loaders.book.list( {author_id: author.id }) },
67 },
68
69 RootQuery: {
70 author(_, { id }, ctx){ return ctx.loaders.author.get(id) },
71 book(_, { title }, ctx){ return ctx.loaders.book.getByTitle(title) },
72 },
73
74 RootMutation: {
75 addBook(_, { title, genre, author_id }, ctx){
76 return ctx.loaders.book.createBook({ title: title, genre: genre, author_id: author_id });
77 },
78 },
79};
80export default resolveFunctions;
81```
82
83And in a file that defines the data loaders:
84```
85// imports ...
86
87const loaders = {
88 book: {
89 createBook(args){
90 return knex('books').insert({ ...args });
91 },
92 },
93 // etc.
94};
95
96export default loaders;
97```
98
99
100Providing a schema in this format has the advantage of staying relatively close
101to graphql-js while at the same time separating the type system from the
102resolve rules for clarity.
103
104Separating data loaders from resolve functions makes them easier to reason about and to test. It
105also means that the only stateful part is clearly separated from the rest of the system, which
106has benefits for scaling.
107
108It is still possible to dynamically generate the resolve functions, as they just
109have to be exported from the file that Apollo Proxy imports for the schema.
110
111
112It is also possible to not use the shorthand with resolve definitions and simply
113upload a schema for graphql-js in the standard format.