12/08/2018, 17:43

Xây dựng một simple GraphQL API Server với NodeJS và Express - Part 2

Tiếp tục bài viết trước, bài này chúng ta cùng tiếp tục tìm hiểu tiếp cách xây dựng một API sử dụng GraphQL, cùng với NodeJS và Express. GraphQL API implementation using GraphQL schema language Chúng ta sẽ cần package lodash. Package này là một bộ các function của Javascript giúp cung cấp các ...

Tiếp tục bài viết trước, bài này chúng ta cùng tiếp tục tìm hiểu tiếp cách xây dựng một API sử dụng GraphQL, cùng với NodeJS và Express.

GraphQL API implementation using GraphQL schema language

Chúng ta sẽ cần package lodash. Package này là một bộ các function của Javascript giúp cung cấp các clean và performance methods để thao tác với các object và collections. Nếu bạn đã quen thuộc với thư viện underscore, điều đó thật là tuyệt vời ! Vì lodash được tạo ra từ đó và có một số sửa đổi để cung cấp chức năng bổ sung và đối phó với một số vấn đề về performance trong thư viện underscore.

npm install lodash --save

Câu lệnh trên sẽ thực hiện cài đặt lodash và save nó như một dependency trong file package.json.

Thêm code sau vào đầu file schema.js của bạn:

const _ = require('lodash');

Dòng code trên đơn giản là để có thể sử dụng thư viện lodash trong file schema.js.

Bây giờ chúng ta hãy cùng xem xét file schema.js dưới đây. Bạn có thể xem chi tiết file này trên github tại đây:

// schema.js
const _ = require('lodash');

// Authors and Posts get data from JSON Arrays in the respective files.
const Authors = require('./data/authors');
const Posts = require('./data/posts');

/* Here a simple schema is constructed without using the GraphQL query language. 
  e.g. using 'new GraphQLObjectType' to create an object type 
*/

let {
  // These are the basic GraphQL types need in this tutorial
  GraphQLString,
  GraphQLList,
  GraphQLObjectType,
  // This is used to create required fileds and arguments
  GraphQLNonNull,
  // This is the class we need to create the schema
  GraphQLSchema,
} = require('graphql');

const AuthorType = new GraphQLObjectType({
  name: "Author",
  description: "This represent an author",
  fields: () => ({
    id: {type: new GraphQLNonNull(GraphQLString)},
    name: {type: new GraphQLNonNull(GraphQLString)},
    twitterHandle: {type: GraphQLString}
  })
});

const PostType = new GraphQLObjectType({
  name: "Post",
  description: "This represent a Post",
  fields: () => ({
    id: {type: new GraphQLNonNull(GraphQLString)},
    title: {type: new GraphQLNonNull(GraphQLString)},
    body: {type: GraphQLString},
    author: {
      type: AuthorType,
      resolve: function(post) {
        return _.find(Authors, a => a.id == post.author_id);
      }
    }
  })
});

// This is the Root Query
const BlogQueryRootType = new GraphQLObjectType({
  name: 'BlogAppSchema',
  description: "Blog Application Schema Root",
  fields: () => ({
    authors: {
      type: new GraphQLList(AuthorType),
      description: "List of all Authors",
      resolve: function() {
        return Authors
      }
    },
    posts: {
      type: new GraphQLList(PostType),
      description: "List of all Posts",
      resolve: function() {
        return Posts
      }
    }
  })
});

// This is the schema declaration
const BlogAppSchema = new GraphQLSchema({
  query: BlogQueryRootType
  // If you need to create or updata a datasource, 
  // you use mutations. Note:
  // mutations will not be explored in this post.
  // mutation: BlogMutationRootType 
});

module.exports = BlogAppSchema;

Nếu bạn nhận thấy trong PostType, chúng ta có một attribute resolve. Chức năng của giải quyết là thực hiện các hoạt động liên quan đến thao tác dữ liệu hoặc chuyển đổi với một giá trị được trả về ở cuối của hoạt động.

Các Types và Query thì đã được thảo luận ở trên. BlogAppSchema sẽ được export sang file server.js bằng cách sử dụng module.exports và bằng cách export BlogAppSchema, chúng ta tạo mọi thứ có sẵn cho file server.js.

Tạo file aserver.js trong thư mục root và thêm code này:

// server.js

/*  
    Required modules {express and express-graphql} 
    will be imported along with the schema object
    from the schema.js file in src/schema.js 
*/

const express = require('express');
const graphqlHTTP = require('express-graphql');
const schema = require('./src/schema.js');

let port = 3000;
const app = express();
app.use('/', graphqlHTTP({
  schema: schema,
  graphiql: true //set to false if you don't want graphiql enabled
}));

app.listen(port);
console.log('GraphQL API server running at localhost:'+ port);

Chúng ta có thể mở sử dụng localhost:3000 để test. Trong thư mục rooot ta mở terminal và gõ lệnh:

node server.js

Kết quả: /pictures/picfullsizes/2018/08/12/poo1534046945.png

Đây là cách server sẽ thực hiện và graphiql sẽ giúp bạn truy vấn API của bạn ngay trong browser. Để test API ta thực hiện query sau:

{
    posts{
        id
       title
       author{
            name
        }
    }
}

Kết quả:

References

https://scotch.io/@codediger/build-a-simple-graphql-api-server-with-express-and-nodejs

0