@@ -31,6 +31,8 @@ include ../_util-fns
31
31
32
32
- [Appendix: Setting up a GraphQL server](#server)
33
33
34
+ - [Full Example](#example)
35
+
34
36
:marked
35
37
**See the <live-example name="heroes-graphql"></live-example>**.
36
38
@@ -288,12 +290,20 @@ code-example(language="json").
288
290
:marked
289
291
## Further resources
290
292
291
- * [GraphQL.org](http://graphql.org/) is a great website, with the following sections:
293
+ * [GraphQL.org](http://graphql.org/) is a great website, with the following sections
294
+ (by the way, all the examples on the website are runing live, try to edit them in the browser while you reading it):
292
295
* [Learn](http://graphql.org/learn/)
293
296
* [Implementations in any language](http://graphql.org/code/)
294
297
* [Community](http://graphql.org/community/)
295
- * [Apollo Developer resources](http://dev.apollodata.com/) - The [team](http://www.apollodata.com/) behind the Angular GraphQL client
298
+ * [Apollo Developer resources](http://dev.apollodata.com/) - The [team](http://www.apollodata.com/) behind the Angular GraphQL client,
299
+ there you will find a more advanced resources about:
300
+ * [Handling updates from the server and managing the local store](http://dev.apollodata.com/angular2/receiving-updates.html)
301
+ * [Authentication](http://dev.apollodata.com/angular2/auth.html)
302
+ * [Pagination](http://dev.apollodata.com/angular2/pagination.html)
303
+ * [Server-side rendering](http://dev.apollodata.com/angular2/server-side-rendering.html)
304
+ * and more..
296
305
* [Apollo Dev Blog](https://dev-blog.apollodata.com/) - The most popular GraphQL blog
306
+ * [Apollo Client Developer Tools](https://dev-blog.apollodata.com/apollo-client-developer-tools-ff89181ebcf#.n5f3fhbg2) - GraphQL debugging tools for Apollo Client in the Chrome developer console
297
307
298
308
.l-main-section
299
309
<a id =" server" ></a >
@@ -309,20 +319,112 @@ code-example(language="json").
309
319
:marked
310
320
You can learn how to run a full GraphQL backend on the [Apollo Server docs](http://dev.apollodata.com/tools/).
311
321
The good thing is, that because it's Isomorphic Javascript, it is almost identical to the simple server we will run inside our Angular app
322
+ so everything we'll learn now will be the same when you would want to move to write a GraphQL backend.
323
+
324
+ Also, there are few GraphQL based Backend-as-a-service platforms out there, like Firebase but based on GraphQL API, to help get
325
+ started really fast - https://www.scaphold.io/ https://www.graph.cool/
312
326
:marked
313
327
To start, let's create a file called `in-memory-graphql.ts` inside our Angular app.
314
328
315
329
First thing we should do is to create our GraphQL schema.
330
+
331
+ For that we will use the `graphql-tools` library that let's us write a GraphQL schema as a string and make it executable:
332
+ code-example( language ="sh" class ="code-shell" ) .
333
+ npm install graphql-tools --save
334
+ :marked
335
+ Now for the schema itself:
336
+ + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'graphql-schema' , 'Heroes GraphQL Schema' )
316
337
.l-sub-section
317
338
:marked
318
- The schema is pretty self explanatory, but if you want to dig deeper, check out [GraphQL.org learn section](http://graphql.org/learn/)
319
- + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'graphql-schema' , 'Heroes GraphQL Schema' )
339
+ The schema is pretty self explanatory, but if you want to dig deeper, check out [GraphQL.org `learn` section](http://graphql.org/learn/)
340
+ :marked
341
+ Next let's create our in-memory data:
342
+ + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'heroes-array' , 'Heroes Array' )
320
343
:marked
344
+ Now we need to write a server that will resolve the queries that we will get from the client based on the schema.
321
345
346
+ The GraphQL server consists of resolver functions that correspond to the types of the schema.
347
+ .l-sub-section
348
+ :marked
349
+ For the full explanation about how GraphQL resolvers work check out the [execution section](http://graphql.org/learn/execution/) of GraphQL.org
350
+ :marked
351
+ Let's create our resolvers:
352
+ + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'resolvers' , 'Resolvers' )
353
+ :marked
354
+ We also used some functions from `lodash` so don't forget to install them from npm and import them:
355
+ + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'import-lodash' , 'Importing lodash' )
356
+ :marked
357
+ As you can see, we created functions that correspond to each type of our schema and also to the mutations.
322
358
359
+ This mechanism makes writing simple GraphQL servers very easy, you simply think about how to resolve a specific type of data,
360
+ separates the frontend logic from the backend, removing the coupling between frontend and backend.
323
361
362
+ .l-sub-section
363
+ :marked
364
+ Also in case you don't have the option to run GraphQL on the server, it's much easier to handle multiple REST requests and join logic on the client using these tools
365
+ :marked
366
+ Now we need to connect the shema to the resolvers with the `makeExecutableSchema` function from
367
+ the [graphql-tools](http://dev.apollodata.com/tools/graphql-tools/index.html) library:
368
+ + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'import-graphql-tools' , 'importing graphql-tools' )
369
+ + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'make-executable-schema' , 'makeExecutableSchema' )
370
+ :marked
371
+ Now that we have executable schema, let's execute it using the `graphql` library and export it so we can use it in our Apollo Client:
372
+ + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'import-graphql' , 'Dont forget to npm install' )
373
+ + makeExample('heroes-graphql/ts/app/in-memory-graphql.ts' , 'execute-and-export' , 'Execute and export' )
374
+ :marked
375
+ Now all that's left is to connect the new in-memory server into our Apollo Client configuration:
376
+ + makeExample('heroes-graphql/ts/app/client.ts' , '' , 'client.ts' )
377
+ :marked
378
+ That's it. now you can run your application as if you had a GraphQL server connected to it but,
379
+ there is no persistance - everything is running in-memory browser right now, so when you refresh the page, all changes will be lost.
324
380
381
+ more things you can do now that you have it setup:
382
+ * You can store everything on the browser's local-storage using local-storage database libraries
383
+ * You can make the resolver functions call your server's existing REST endpoint
384
+ * You can start a separate Node GraphQL server and simply move the code in there -
385
+ now you will have persistance and you became a backend developer ;)
325
386
387
+ .l-main-section
388
+ <a id =" example" ></a >
389
+ :marked
390
+ ## Full Example
391
+
392
+ block file-summary
393
+ + makeTabs(
394
+ ` heroes-graphql/ts/app/app.component.ts,
395
+ heroes-graphql/ts/app/app.module.ts,
396
+ heroes-graphql/ts/app/heroes.component.ts,
397
+ heroes-graphql/ts/app/heroes.component.html,
398
+ heroes-graphql/ts/app/heroes.component.css,
399
+ heroes-graphql/ts/app/hero-detail.component.ts,
400
+ heroes-graphql/ts/app/hero-detail.component.html,
401
+ heroes-graphql/ts/app/in-memory-graphql.ts,
402
+ heroes-graphql/ts/app/client.ts` ,
403
+ ',,,,,,,,' ,
404
+ ` app.comp...ts,
405
+ app.mod...ts,
406
+ heroes.comp...ts,
407
+ heroes.comp...html,
408
+ heroes.comp...css,
409
+ hero-detail.comp...ts,
410
+ hero-detail.comp...html,
411
+ in-memory-graphql.ts,
412
+ client.ts`
413
+ )
414
+
415
+ + makeTabs(
416
+ ` toh-6/ts/app/app-routing.module.ts,
417
+ toh-6/ts/app/hero-search.component.ts,
418
+ toh-6/ts/app/hero-search.component.html,
419
+ toh-6/ts/app/hero-search.component.css,
420
+ toh-6/ts/app/rxjs-extensions.ts` ,
421
+ null ,
422
+ ` app-routing.modules.ts,
423
+ hero-search.component.ts,
424
+ hero-search.component.html,
425
+ hero-search.component.css,
426
+ rxjs-extensions.ts`
427
+ )
326
428
327
429
:marked
328
430
[Back to top](#top)
0 commit comments