Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 326f89e

Browse files
kapunahelewongUrigo
authored andcommitted
docs(cookbook/graphql): full first editorial pass
1 parent f5b217a commit 326f89e

File tree

1 file changed

+176
-56
lines changed

1 file changed

+176
-56
lines changed

public/docs/ts/latest/cookbook/graphql.jade

Lines changed: 176 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,10 @@ code-example(language="sh" class="code-shell").
412412

413413
.l-sub-section
414414
:marked
415-
You can look at it as the equivalent of POST request in REST
415+
You can look at it as the equivalent of a POST request in REST.
416416
:marked
417+
GraphQL mutations, like queries, are straightforward with minimal syntax.
418+
Consider this example of a mutation:
417419
code-example(language="json").
418420
mutation {
419421
addHero(heroName: "Russell Brand") {
@@ -422,12 +424,16 @@ code-example(language="json").
422424
}
423425
}
424426
:marked
425-
GraphQL mutations consist of two parts:
426-
1. The mutation name with arguments (`addHero`), which represents the actual operation to be done on the server (just like calling a function)
427-
2. The fields you want back from the result of the mutation to update the client (`id` and `name`) - which is very powerful - You, as the client developer can
428-
decide which fields you will get back, not something that the server will dictate for you
427+
First, you declare that you're writing a mutation and then specify what it does.
428+
To break it down, GraphQL mutations consist of two parts:
429+
1. The mutation name with arguments (`addHero`), which represents the actual
430+
operation to be done on the server (just like calling a function).
431+
2. The fields you want back from the result of the mutation. These update the client.
432+
In this example, they are `id` and `name`. This allows you to decide
433+
which fields you get back from the server,
434+
rather than the server dictating what's returned.
429435

430-
The result of the above mutation might be be:
436+
The result of the above mutation might be:
431437
code-example(language="json").
432438
{
433439
"data": {
@@ -439,20 +445,50 @@ code-example(language="json").
439445
}
440446
.l-sub-section
441447
:marked
442-
You can get deep into the mutation syntax on the [GraphQL.org website](http://graphql.org/learn/queries/#mutations)
448+
For an in-depth look at mutation syntax, see the [Mutations
449+
documentation](http://graphql.org/learn/queries/#mutations)
450+
at [GraphQL.org](http://graphql.org).
443451
:marked
444-
So first let's add a local function to add a hero to our template:
452+
To use a mutation, first update the template with a function to add a hero:
445453
+makeExample('heroes-graphql/ts/src/app/heroes.component.html', 'add', 'heroes.component.html')
446454
:marked
447-
and component:
455+
In the component class, create the `add()` function. It expects a name argument of type `string`
456+
and is `void` because it returns nothing.
448457
+makeExample('heroes-graphql/ts/src/app/heroes.component.1.ts', 'add', 'heroes.component.ts')
449458
:marked
450-
and now let's add an `addHero` mutation to that function using the `apollo.mutate` function:
459+
Now for the fun part. Inside of the `add()` function, add an `addHero` mutation
460+
using the `apollo.mutate` function as follows:
451461
+makeExample('heroes-graphql/ts/src/app/heroes.component.ts', 'add-mutation', 'heroes.component.ts')
452462
:marked
453-
You can see, that our mutation requires and variable and we pass it to the `mutate` function through the `variables` param.
463+
The mutation requires and variable and we pass it to the `mutate` function through the `variables` param.
464+
.alert.is-important
465+
:marked
466+
Uri: Could you explain this above segment section by section?
467+
You've already explained the part in green, so you shouldn't
468+
have to say much about it. The rest, though, could benefit from
469+
a little guiding prose. Two or
470+
three short paragraphs should be fine. We just want the reader to
471+
understand at least the gist of what each part of the code we give
472+
them is doing. I'd explain these but have only the vaguest notion
473+
of what's going on. Pretend you are explaining it to me. I don't know what
474+
the tick marks are doing (are they like a template string?). I have a cursory understanding
475+
of what an observable is...I see we are pushing the `id` and `name` but
476+
don't quite understand how/when. The subscribe syntax loses me. Lastly,
477+
I don't know why we are setting the `selectedHero` to `null`.
478+
479+
:marked
480+
Just like a query, the mutate function returns an Observable you can subscribe to
481+
that handles the data you request.
454482

455-
Also, just like a query, the mutate function returns an Observable we can subscribe to and handle the data we asked for.
483+
.alert.is-important
484+
:marked
485+
Uri: Let's say something here about how we can now add a hero. Can the
486+
reader now click their add button and their new hero be added? Can we
487+
show this in a gif or a screenshot? Showing the achievement could
488+
make the point about how beneficial GraphQL is very quickly.
489+
Imagine the reader coming to this page and giving it a cursory scroll
490+
to see how long it is in deciding whether or not to work through it.
491+
A gif (especially) or screenshot could help them decide to do it.
456492

457493
.l-main-section
458494
<a id="resources"></a>
@@ -479,79 +515,163 @@ code-example(language="json").
479515
:marked
480516
## Appendix: Setting up a GraphQL server
481517

482-
We are going to show you how to add a GraphQL server in Javascript.
518+
Running the server in the browser helps you start using
519+
GraphQL on your frontend without having a GraphQL backend.
520+
If you don't have the option of running GraphQL on the server,
521+
this method makes it easier to handle multiple REST
522+
requests and join logic on the client.
483523

484-
Like the other examples on angular.io, we are going to run the server in the browser as part of our Angular app,
485-
it's good for testing and also if you want to start using GraphQL on your frontend without having a GraphQL backend.
524+
.alert.is-important
525+
:marked
526+
Uri: Can you tell me why it makes it easier? We should say
527+
"...logic on the client because..."
486528

487529
.l-sub-section
488530
:marked
489-
You can learn how to run a full GraphQL backend on the [Apollo Server docs](http://dev.apollodata.com/tools/).
490-
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
491-
so everything we'll learn now will be the same when you would want to move to write a GraphQL backend.
531+
To read more about how to run a full GraphQL backend, see the [Apollo Server documentation](http://dev.apollodata.com/tools/).
532+
Because the real, backend server is written in Isomorphic Javascript,
533+
it is almost identical to the local server in this appendix.
534+
Everything you learn here applies to writing an actual GraphQL backend server.
492535

493-
Also, there are few GraphQL based Backend-as-a-service platforms out there, like Firebase but based on GraphQL API, to help get
494-
started really fast - https://www.scaphold.io/ https://www.graph.cool/
495-
:marked
496-
To start, let's create a file called `in-memory-graphql.ts` inside our Angular app.
536+
Additionally, there are a few GraphQL based backend-as-a-service platforms available,
537+
such as Firebase, but they are based on the GraphQL API. For help on getting
538+
up and running, see [Scaphold](https://www.scaphold.io/) and [Graphcool](https://www.graph.cool/).
497539

498-
First thing we should do is to create our GraphQL schema.
540+
.alert.is-important
541+
:marked
542+
Uri: Can you explain why the GraphQL API makes using things like Firebase different?
543+
There's a "but" in that sentence, but I don't know what it implies.
544+
545+
:marked
546+
In order to create a GraphQL schema, you need the `graphql-tools` library.
547+
It allows you to write a GraphQL schema as a string and make it executable.
548+
In a terminal window, issue the following command:
499549

500-
For that we will use the `graphql-tools` library that let's us write a GraphQL schema as a string and make it executable:
501550
code-example(language="sh" class="code-shell").
502551
npm install graphql-tools --save
552+
503553
:marked
504-
Now for the schema itself:
505-
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'graphql-schema', 'Heroes GraphQL Schema')
554+
Next, create a file called `in-memory-graphql.ts` in the `app` directory
555+
and paste in the following schema:
556+
557+
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'graphql-schema', 'in-memory-graphql.ts')
558+
559+
.alert.is-important
560+
:marked
561+
Uri: Could you change the use of "we" in the above comments to "you" or the imperative (command without
562+
"you")?
506563
.l-sub-section
507564
:marked
508-
The schema is pretty self explanatory, but if you want to dig deeper, check out [GraphQL.org `learn` section](http://graphql.org/learn/)
565+
While the schema includes the major points covered in this cookbook,
566+
you can read more in the [GraphQL.org Introduction to GraphQL](http://graphql.org/learn/).
509567
:marked
510-
Next let's create our in-memory data:
511-
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'heroes-array', 'Heroes Array')
568+
Now, create your in-memory data:
569+
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'heroes-array', 'in-memory-graphql.ts')
512570
:marked
513-
Now we need to write a server that will resolve the queries that we will get from the client based on the schema.
571+
The next step is writing a server that _resolves_
572+
the queries from the client based on the schema.
573+
Hence, the GraphQL server consists of _resolver
574+
functions_ that correspond to the _types_ of the schema.
575+
576+
To create the resolvers, copy the following code and add it to `in-memory-graphql.ts`.
577+
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'resolvers', 'in-memory-graphql.ts')
514578

515-
The GraphQL server consists of resolver functions that correspond to the types of the schema.
516579
.l-sub-section
517580
:marked
518-
For the full explanation about how GraphQL resolvers work check out the [execution section](http://graphql.org/learn/execution/) of GraphQL.org
519-
:marked
520-
Let's create our resolvers:
521-
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'resolvers', 'Resolvers')
581+
For the full explanation about how GraphQL resolvers work see
582+
[Execution](http://graphql.org/learn/execution/) on [GraphQL.org](http://graphql.org/).
583+
522584
:marked
523-
We also used some functions from `lodash` so don't forget to install them from npm and import them:
524-
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'import-lodash', 'Importing lodash')
585+
You may have noticed some functions from `lodash` such as `lodashFind()` so don't
586+
forget to install them from npm and import them:
587+
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'import-lodash', 'in-memory-graphql.ts (imports)')
588+
589+
.alert.is-important
590+
:marked
591+
Uri: What is the npm install command for the lodash functions?
592+
Do we install the whole lodash library or just the functions?
593+
(I've never used lodash before).
594+
595+
525596
:marked
526-
As you can see, we created functions that correspond to each type of our schema and also to the mutations.
597+
Notice that the server includes functions that correspond to each
598+
type in the schema _and_ the mutations.
527599

528-
This mechanism makes writing simple GraphQL servers very easy, you simply think about how to resolve a specific type of data,
529-
separates the frontend logic from the backend, removing the coupling between frontend and backend.
600+
This mechanism makes writing simple GraphQL servers straightforward&mdash;you simply
601+
resolve a specific type of data.
602+
This removes the coupling between frontend and backend.
530603

531-
.l-sub-section
604+
.alert.is-important
532605
:marked
533-
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
606+
Uri: I don't know how to incorporate this: "separate the
607+
frontend logic from the backend". And I don't know if
608+
I'm right about "This removes the coupling between frontend and backend".
609+
I was trying to make it clearer by breaking it into smaller ideas, but
610+
I'm not sure what those ideas should be.
611+
534612
:marked
535-
Now we need to connect the shema to the resolvers with the `makeExecutableSchema` function from
613+
Now, connect the schema to the resolvers with the `makeExecutableSchema` function from
536614
the [graphql-tools](http://dev.apollodata.com/tools/graphql-tools/index.html) library:
537-
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'import-graphql-tools', 'importing graphql-tools')
538-
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'make-executable-schema', 'makeExecutableSchema')
615+
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'import-graphql-tools', 'in-memory-graphql.ts (excerpt)')
616+
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'make-executable-schema', 'in-memory-graphql.ts (excerpt)')
617+
618+
:marked
619+
In the constant `schema`, `makeExecutableSchema` has two properties,
620+
`typeDefs` and `resolvers`. Here, you define them with the `typeDefinitions`
621+
and `resolveFunctions` that you created earlier in `in-memory-graphql.ts`.
622+
This way, your app/GraphQL? (Uri - can you correct me here?) knows where to look
623+
for definitions and resolvers.
624+
625+
:marked
626+
Now that you have an executable schema, execute it using the `graphql`
627+
library and export it so you can use it with the Apollo Client.
628+
First, `npm install`:
629+
630+
.alert.is-important
631+
:marked
632+
Uri: can you provide the npm install command?
633+
539634
:marked
540-
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:
541-
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'import-graphql', 'Dont forget to npm install')
542-
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'execute-and-export', 'Execute and export')
635+
Next, add an import statement for `execute`.
636+
637+
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'import-graphql', 'in-memory-graphql.ts (excerpt)')
638+
639+
.alert.is-important
640+
:marked
641+
Uri: Could you explain what's happening in the below?
642+
This will probably take 2-3 short paragraphs. Just a
643+
general tour from top to bottom.
644+
+makeExample('heroes-graphql/ts/src/app/in-memory-graphql.ts', 'execute-and-export', 'in-memory-graphql.ts (excerpt)')
543645
:marked
544-
Now all that's left is to connect the new in-memory server into our Apollo Client configuration:
646+
Now all that's left is to connect the new in-memory server to the Apollo Client configuration
647+
by importing `networkInterface` and adding it to the `client` constant in `client.ts`.
545648
+makeExample('heroes-graphql/ts/src/app/client.ts', '', 'client.ts')
546649
:marked
547-
That's it. now you can run your application as if you had a GraphQL server connected to it but,
548-
there is no persistance - everything is running in-memory browser right now, so when you refresh the page, all changes will be lost.
650+
That's it. Now you can run your application as if you had a GraphQL server connected to it.
651+
However, there is no persistance&mdash;everything is running in-memory in the browser,
652+
so when you refresh the page, all changes will be lost.
653+
654+
Now that you have a local server set up, you have some options:
655+
* You can store everything on the browser's local-storage using local-storage database libraries.
656+
* You can make the resolver functions call your server's existing REST endpoint.
657+
* You can start a separate Node GraphQL server and simply move the code into it for persistance.
658+
659+
.alert.is-important
660+
:marked
661+
Uri: Let's add a conclusion showing what was accomplished in the doc.
662+
Maybe something like (please add anything I've missed):
663+
664+
.l-main-section
665+
:marked
666+
## Conclusion
667+
668+
This cookbook covered:
669+
670+
- How to create a basic GraphQL query.
671+
- How to create a basic GraphQL mutation.
672+
- How to build a GraphQL server.
673+
549674

550-
more things you can do now that you have it setup:
551-
* You can store everything on the browser's local-storage using local-storage database libraries
552-
* You can make the resolver functions call your server's existing REST endpoint
553-
* You can start a separate Node GraphQL server and simply move the code in there -
554-
now you will have persistance and you became a backend developer ;)
555675

556676
.l-main-section
557677
<a id="example"></a>

0 commit comments

Comments
 (0)