First, the advantage over REST services Imaging you have a web app which manages a list of people. Each of them has a few friends. That becomes a “Graph” which is a CS data-structure term for items linked together with directional or un-directional relations. If that is for REST API design, I probably have to write quite a few ones like get-people-by-id and get-people-friends-count-by-id and get-people-friends-details-by-id If you want to get all the data, you either have to make 3 calls to get all these info above or you combine all these 3 things at server end and return back everything no matter what the user asked for. This is what is called and over fetching under fetching GraphQL solution looks much more elegant.For situation we just need People basic info without any details query { People(id: 123){ name age } } For situation we want more info query { People(id: 123){ name age friendsCount friends{ name age } } } Even better, we can deep dive to the friends relationship loop hole query { People(id: 123){ name age friendsCount friends{ name age friends{ name age } } } } GraphQL basic building blocks: Type, Query, Mutation and Subscription is just like Object or Noun in our human languages. In the example above, People is just a type, it should look like this: (! means it’s required) Type type People { id: ID! name: String! age: Int friendsCount: Int friends: [People] } To describe a list, use the [] syntax just like javascript. Here are more details examples are shown in the paragraph above, it’s just like a type of query language using description way. Query is to update/change/remove/add data based on the types Mutation mutation { addPeople(name: "John Doe" age:21) { id age name } } are like the pub/sub way in messaging system. In most popular GraphQL server implementations, they are implemented using WebSocket and some solutions that support pub/sub like Redis etcWe can build a chatting app using GraphQL Subscriptions without knowing how it’s implemented under the hood using Websockets, very neat. Subscriptions The following key points are very easy to overlook but very important Type, Query, Mutation and Subscription are defined in the Schema which is like your database’s create schema scripts.All of them starts with word ` ` Type type Subscription { messageAdded(channelId: ID!): Message } type query{ allPeople: [People] } type mutation{ addPeople(name:String! age:Int): People } 2. In your app client or the client tools like GraphiQL or GraphQL Playground, use commands like query, mutation and subscription. In short, define them using type query type mutation and type subscription first then use them in client Don’t get confused by their client usage syntax and their schema definition syntax as I did before :) subscription { messageAdded(channelId: 1) { id text } } 3. Query, Mutation and Subscription all can take parameters.It looks like this query getPhotos($filter:PhotoFilter $page:DataPage $sort:DataSort) { allPhotos(filter:$filter paging:$page sorting:$sort){ ... } } Wearing double socks When I started, I though those addPeople(name:String age:Int) things are parameters, why do we need those $xxx things.Isn’t it just like a man wearing double socks? Actually those $.. things like the getPhotos commands above are for and the allPhotos ones are for .This does help me to understand the syntax and hope it makes sense to you too.allPhotos(…) will be sent to the server so it can resolve the answer and send back the result.On the Client side (either App client code or GraphiQL tool), you can provide the parameter(input variables) like this below Client Server Notice you can provide the variable in the left-bottom corner of the tool for the $input variable in the mutation statement above.That UserInput! is a , just another type which is for input variables definitions Input Type 4. All the parameter and type elements like the id, username, email, phone listed above are separated by but not commas. space or new-line Pay attention to the query/mutation statement below, it’s a space, not comma allPhotos(filter:$filter paging:$page sorting:$sort) This is very easy to overlook especially the variables part showing above uses commas to separate individual variables 5. Listing all the entries for a type like the id, username, email, phone above can be tedious especially if you have to specify them again and again. So there comes a handy thing called Fragment fragment userDetails on User { id username email phone ... ... } Then whenever we need to get User, we can use the fragment getUser(id: 123){ ...userDetails } It’s pretty much like the Javascript ES6 … operator 6. Other interesting types. is just a combination of different typesIf we have 2 types like StudyGroup and Workout, we can union them Union Type union AgendaItem = StudyGroup | Workout Then when we query this new type, we can use the special syntax to dynamically get related attributes. query schedule { agenda { …on Workout { name reps } …on StudyGroup { name subject students } } } . it’s like fragment but fragment is for , Interface is for . It just takes the common fields from different types so all those types can share common attributes Interface query and mutation type definitions interface AgendaItem { name: String! start: DateTime! end: DateTime! } type StudyGroup implements AgendaItem { name: String! start: DateTime! end: DateTime! participants: [User!]! topic: String! } type Workout implements AgendaItem { name: String! start: DateTime! end: DateTime! reps: Int! } GraphQL has a lot of terms and concepts, so here comes my quick reference which I wish I knew them when I started. For GraphQL server to work, we need to provide and Schema Resolvers Schema is just all the Type, Query, Mutation and Subscription we talked above. Advanced types are like , , Enum Scalar List, Union, Fragment and Interface Resolver is the implementation functions to retrieve data for the queries and mutations For the client side, use query, mutation and subscriptionFor the server side schema definition, use type query type mutation and type subscription These can also take as input, so you can group variables together to create which is just variable collection definitionsRefer to the GraphiQL screenshot above, that UserInput! is a custom Input Type Variables InputType The following is an example to use App client code to do similar mutation call like the GraphiQL example Notice the mutation statement and variables are sent separately just like the GraphiQL sample above. import { request } from 'graphql-request' var url = 'http://localhost:4000/graphql' var mutation = ` mutation populate($count: Int!) { addFakeUsers(count:$count) { id name } } ` var variables = { count: 3 } request(url, mutation, variables) .then(console.log) .catch(console.error) It took me quite some time to get over that many terms and understand the nuance between the server definition and the client request syntax. Hope you find all these helpful and use it to refresh the basic knowledge over time. Cheers and claps :)
Share Your Thoughts