This paper will briefly introduce the GraphQL front-end practice, using Express + Express-GraphQL + graphqL.js to build a simple book query, modify, add GraphQL interface.

A quick introduction to GraphQL

  • GraphQL is a query language + back-end parse query runtime: it doesn’t rely on any database or any back-end implementation and can be built from your existing back-end code and data store, following GraphQL’s data definition.
  • One interface for adding, deleting, modifying and querying all data: Data definition in GraphQL service can provide a unified interface for front-end query of various data.

Compare with traditional Restful apis

Suppose we have a business that queries author information for the title JAVASCRIT Advanced Programming. Here’s a comparison between using Restful apis and GraphQL

  • Using a Restful API
  1. First through request"/books? name=xxx"Obtain the book information of the title “JAVASCRIT Advanced Programming”, and obtain the author ID from the book information through the code.
  2. Repass request"/author? id=xxx"Get author details
  • Using GraphQL

Using a query language such as the following GraphQL, you can complete the query on a single request.

{
  authorOfBook(bookName:"JAVASCRIT Advanced Programming"){
    name
    age
    address
    id
  }
}
Copy the code

The above is a GraphQL query that looks like a method that takes an argument (bookName). This method returns a JSON file containing fields such as name, age, Address, ID, and so on. When we actually use GraphQL, we just need to send the information with the query structure to the service interface provided by GraphQL to get the Author information we want. The above example actually returns an author, consistent with the query definition parameters, as shown below

{
 name:"Matt Frisbie".age:55.address:Chaoyang District, Beijing.id:10010011
}
Copy the code

The query parameters of GraphQL above work because of the corresponding definition of the back-end GraphQL, which mainly contains the query field, field type, and how to value. For example, name, age, address, AND ID are all defined in GraphQL. If there is no definition, the corresponding query will report an error.

By defining the supported query types, field queries can be carried out as needed (the back-end GraphQL service will directly return only the fields desired by the front-end according to the query information, instead of all the information of author). For example, only the author name information can be directly queried like this:

{
  author(bookName:"JAVASCRIT Advanced Programming"){
    name
  }
}
Copy the code

The returned value will only have:

{
 name:"Matt Frisbie",}Copy the code

Practice a

Create a Node Express project

Through a book query and modify demo to demonstrate the practice of GraphQL, mainly involving query type definition, query parameter transfer.

Create a Node Express project and install graphqL. js with the expess-GraphQL dependency (a FaceBook implementation of the GraphQL JS library).

mkdir my-first-graphql
cd my-first-graphql
npm init
npm i express graphql express-graphql
Copy the code

Write basic Express code

touch index.js
Copy the code

Write the following code to configure a GraphQL service that supports the Hello field query (return “Hello world”).

const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { GraphQLSchema } = require('graphql');
const { GraphQLObjectType, GraphQLString } = require('graphql/type');

// Here is the definition of the supported query | modification, defined by GraphQL Schema
var schema = new GraphQLSchema({
    query: new GraphQLObjectType({
        name: 'root'.fields: {
            hello: {
                type: GraphQLString,
                resolve: () = > 'hello world',},},}),});var app = express();

// Here is the registration for the entry query of the GraphQL service, which needs to pass in the schema
app.use(
    '/graphql',
    graphqlHTTP({
        schema: schema,
        graphiql: true,})); app.listen(4000);
console.log('Running a GraphQL API server at http://localhost:4000/graphql');

Copy the code
  • The GraphQLSchema constructor parameter requires an object to be passed in. Query: specifies an interface of the query type. If you want to define a modification or addition, you will change it to mutation.
  • The value of query: needs to be a GraphQL, which represents the type of the result returned by the query, and GraphQLObjectType, which indicates that the supported query is an object.
  • Fields: Defines the fields supported by the query, that is, the fields that can be queried in the query language.
  • hello: Hello and its type are String (GraphQLString). In GraphQLJS, all supported types have their own encapsulation. For example, Int (GraphQLInt), List (GraphQLList), Boolean (GraphQLBoolean) and so on are also supported.
  • Resolve: Specifies the value returned by the Hello query

Start the GraphQL backend service

node ./index.js
Copy the code

Open a browser to http://localhost:4000/graphql can see GraphQL service pages, on this page can directly see the existing support query field. You can query GraphQL directly from this page.

For example, our code supports the Hello query. Fill in the following query in the query window and see the result of “Hello World” directly.

query{
  hello   
}
Copy the code

Create a data file of book information to simulate database data.

touch data.js
Copy the code

Write the following so that we have data to query.

var autors = [
  {
    id: 1.name: 'Joe'.desc: 'Good at science fiction'}, {id: 2.name: 'bill'.desc: 'Good at fairy cultivation and fantasy novels'}, {id: 3.name: 'Cathy'.desc: 'Good at urban and romantic novels',}]var books = [
  {
    id: 1001.name: 'I'll wait for you in the future'.autor: 1
  },
  {
    id: 1002.name: 'Time Traveler'.autor: 1
  },
  {
    id: 1003.name: 'Ask the Chief of Lingshan Road'.autor: 2
  },
  {
    id: 1004.name: 'Peach Blossom Land again'.autor: 2
  },
  {
    id: 1005.name: 'The bully CEO doesn't love me'.autor: 3},]module.exports = {
  autors,
  books
}
Copy the code

Events Query all books, author, query books by author, new books, and other examples.

Query all authors

Looking at this, it should be easy to imagine that querying all books should have a query type like the hello query mentioned above. Since Hello is of type string, we don’t have to define it separately. But the book we want to query is a custom type, and we need to define the query type authors. You need a type to define a query interface.

Author and authors see the following code and comments:

The Author type is defined here, and each entry in fileds defines the attributes and types of the Author type
var AuthorType = new GraphQLObjectType({
    name: 'Author'.fields: {
        id: { type: GraphQLInt },
        name: { type: GraphQLString },
        desc: { type: GraphQLString },
    },
});

// A collection type of type Author (List)
var AuthorListType = new GraphQLList(AuthorType);
Copy the code

The GraphQL service knows the field types in the book information, and then defines the schema. Schema tells GraphQL what queries it can provide. See the following code and comments:

// The root query, the outermost available query
var RootQueryType = new GraphQLObjectType({
    name: 'library'.fields: {
       The authors field is defined here to be queried
        authors: {
        // The type of this field is a collection of the Author types defined above.
        type: AuthorListType,
        // The value is false data defined by us
        resolve: () = > authors,
     },
   },
});

// Define the schema, which defines the queries supported by the GraphQL service
const librarySchema = new GraphQLSchema({
    // Here we define the root type of the query
    query: RootQueryType,
});
Copy the code

With the authors query field defined above, we can now change the GraphQL schema for Express to the librarySchema we just defined

app.use(
    '/graphql',
    graphqlHTTP({
        schema: librarySchema,
        graphiql: true,}));Copy the code

Let’s look up all the authors, as shown here

We can also look up only the name, that is, passing only name in the query, as shown

Query all books

Here is the same as querying all authors, directly paste the code.

// The Book type is defined here, and each entry in fileds defines the properties and types of the Book type
var BookType = new GraphQLObjectType({
    name: 'Book'.fields: {
        id: { type: GraphQLInt },
        name: { type: GraphQLString },
        author: { type: GraphQLInt },
    },
});

// A collection type of type Author (List)
var BookListType = new GraphQLList(BookType);

/ / query
var RootQueryType = new GraphQLObjectType({
    name: 'library'.fields: {
        authors: {
            type: AuthorListType,
            resolve: () = > authors,
        },
         // The books field can be queried
        books: {
         // The type of this field is a collection of the Book types defined above.
        type: BookListType,
         // The value is false data defined by us
        resolve: () = > books,
        },
    },
});
Copy the code

Query all books

Query all books and all authors

Query all book titles, and all author names

Query books by author name

Through the above we can already query all the books and authors. The simplest way to query books by author name can be to check all the front end, and then screen in the front end.

Obviously this is not acceptable in real development.

Now let’s support querying books by author name. The first step is to support query parameter passing, and then resolve the data corresponding to the parameters in the Resolve method that defines the query field in GraphQL. Look at the code and comments

/ / query
var RootQueryType = new GraphQLObjectType({
    name: 'library'.fields: {
        authors: {
            type: AuthorListType,
            resolve: () = > authors,
        },
        books: {
            type: BookListType,
            resolve: () = > books,
        },
        // Define a query field to query the book information of the specified author
        booksByAuthor: {
        // The return type is also a collection type of books, like all books
            type: BookListType,
            // Define query parameters
            args: {
                / / parameter name
                name: {
                  // Parameter type
                type: GraphQLString,
                },
            },
            // How to value
            resolve: (parent, args) = > {
                // Find the author ID from the author list using the name field in the query parameter
                const author = authors.find((author) = > author.name === args.name);
                // Find all books by author id
                const targetBooks = books.filter((b) = > b.author === author.id);
		returntargetBooks; }},}});Copy the code

This allows you to look up all books by author name

Of course, you could just look up John’s book title

The new book

Finally, to implement an insert operation, as mentioned earlier, we need to define a schema of type muttion.

const RootMutationType = new GraphQLObjectType({
    name: 'updateLibrary'.fields: {
        addBook: {
          // Define the operation return value type
            type: BookType,
          // Define pass parameters as query
            args: {
                name: {  type: GraphQLString },
                authorId: {type: GraphQLInt },
      },
      // Define how to operate and how to get the return value
      resolve: (parent, args) = > {
            var b = {
                id: books.length + 1000.name: args.name,
                author: args.authorId,
            };
            // Add books
            books.push(b);
            // Return to the book
            returnb; }},}});// Define the schema, which defines the queries supported by the GraphQL service
const librarySchema = new GraphQLSchema({
	query: RootQueryType,
      // Define the entry object type for the modification operation
	mutation: RootMutationType,
});
Copy the code

To add a book named “The End of the Universe” whose author ID is 1. You can see that the added information of the book is returned, and the generated book ID is 1005

To query all books, you can see that they have been added.

Let’s use Postman to query

conclusion

This article introduces the basic concepts of GraphQL and shows how to build a GraphQL backend service under Node through a simple book query example.