SongFuZhen
8/12/2019 - 8:32 AM

Express+GraphQL入门体验

Express-GraphQL搭建一个API服务器

Express + GraphQL 入门

Step1: 初始化项目

mkdir gql-server & cd gql-server

npm init

Step2: 安装依赖

项目中用到如下依赖

npm install graphql express express-graphql --save

为了方便, 可以安装nodemon, 实现改动代码即可重启服务

npm install -g nodemon

Step3: 创建server.js

touch server.js

Step4: 编写代码

完整版代码如下:

var express = require("express");
var express_graphql = require("express-graphql");
var { buildSchema } = require("graphql");

// GraphQL schema
var schema = buildSchema(`
    type Query {
        message: String
        course(id: Int): Course
        courses(topic: String): [Course]
    },
    type Mutation {
        updateCourseTopic(id: Int, topic: String!): Course
    }
    type Course {
        id: Int
        title: String
        author: String
        description: String
        topic: String
        url: String
    }
`);

var coursesData = [
    {
        id: 1,
        title: "The Complete Node.js Developer Course",
        author: "Andrew Mead, Rob Percival",
        description: "Learn Node.js by building real-world applications with Node, Express, MongoDB, Mocha, and more!",
        topic: "Node.js",
        url: "https://codingthesmartway.com/courses/nodejs/"
    },
    {
        id: 2,
        title: "Node.js, Express & MongoDB Dev to Deployment",
        author: "Brad Traversy",
        description: "Learn by example building & deploying real-world Node.js applications from absolute scratch",
        topic: "Node.js",
        url: "https://codingthesmartway.com/courses/nodejs-express-mongodb/"
    },
    {
        id: 3,
        title: "JavaScript: Understanding The Weird Parts",
        author: "Anthony Alicea",
        description:
            "An advanced JavaScript course for everyone! Scope, closures, prototypes, this, build your own framework, and more.",
        topic: "JavaScript",
        url: "https://codingthesmartway.com/courses/understand-javascript/"
    }
];

var getCourse = function(args) {
    var id = args.id;
    return coursesData.filter(course => {
        return course.id == id;
    })[0];
};

var getCourses = function(args) {
    if (args.topic) {
        var topic = args.topic;
        return coursesData.filter(course => course.topic === topic);
    } else {
        return coursesData;
    }
};

var updateCourseTopic = function({ id, topic }) {
    coursesData.map(course => {
        if (course.id === id) {
            course.topic = topic;
            return course;
        }
    });

    return coursesData.filter(course => course.id === id)[0];
};

var root = {
    message: () => "Welcome GraphQL",
    course: getCourse,
    courses: getCourses,
    updateCourseTopic: updateCourseTopic
};

// Create an express server and a GraphQL endpoint
var app = express();

app.use(
    "/graphql",
    express_graphql({
        schema: schema,
        rootValue: root,
        graphiql: true
    })
);

app.listen(4000, () => console.log("Express GraphQL Server Now Running On localhost:4000/graphql"));

Step5: 启动服务

nodemon --inspect ./server.js localhost 4000

Step6: 在打开的网页上直接使用

query message {
  message
}

返回值如下

{
  "data": {
    "message": "Welcome GraphQL"
  }
}

其他方法示例如下:

query message {
  message
}

query getSingleCourse($courseID: Int!) {
  course(id: $courseID) {
    title
    author
    description
    topic
    url
  }
}

query getCourseWithFragments($courseID1: Int!, $courseID2: Int!) {
      course1: course(id: $courseID1) {
             ...courseFields
      },
      course2: course(id: $courseID2) {
            ...courseFields
      } 
}

fragment courseFields on Course {
  title
  author
  description
  topic
  url
}

query getCourses($courseTopic: String!) {
  courses(topic: $courseTopic) {
    ...courseFields
  }
}

mutation updateCourseTopic($id: Int!, $topic: String!) {
  updateCourseTopic(id: $id, topic: $topic) {
    ... on Course {
      title
      author
      description
      topic
      url
    }
  }
}

参数示例如下:

{
  "$courseID": 1
}

{ 
    "courseID1":1,
    "courseID2":2
}

{
  "courseTopic": "Node.js"
}

{
  "id": 1,
  "topic": "JavaScript"
}

使用Postman直接请求

http://localhost:4000/graphql?query=query getSingleCourse($courseID: Int!) {
  course(id: $courseID) {
    title
    author
    description
    topic
    url
  }
}&variables={"courseID" : 1}

返回值如下:

{
    "data": {
        "course": {
            "title": "The Complete Node.js Developer Course",
            "author": "Andrew Mead, Rob Percival",
            "description": "Learn Node.js by building real-world applications with Node, Express, MongoDB, Mocha, and more!",
            "topic": "Node.js",
            "url": "https://codingthesmartway.com/courses/nodejs/"
        }
    }
}