GraphQL 学习

YuanZhea 2019-07-01

GraphQL 学习

一、什么是GraphQL

一种用于 API 的查询语言

二、学习GraphQL

开始撸码学习

1.写一个 server.js 文件

const express = require('express');
const graphqlHTTP = require('express-graphql');
const {buildSchema} = require('graphql');

const schema = buildSchema(`
  type Query {
    hello: String
  }
`);

const root = {hello: () => 'Hello world!'};

const app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
}));
app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));
使用命令
1. 使用 npm init -y 初始化一个 package.json 文件
2. 安装所需插件 npm install express express-graphql graphql -S

GraphQL 学习
GraphQL 学习

遇上错误如上:项目名称不能使用 grapql,修改成 my-graphql

2.启动项目测试

命令: node server.js

GraphQL 学习

遇上端口占用问题,停掉或者改用其他端口。

GraphQL 学习

相关命令: 
    lsof -i :4000
    kill -9 端口号(上图为,47806)

GraphQL 学习

如上所示,启动成功。
访问地址: localhost:4000/graphql

GraphQL 学习

访问成功

3.定义复杂类型

定义一个 学生类型 student
const express = require('express');
const graphqlHTTP = require('express-graphql');
const {buildSchema} = require('graphql');

const schema = buildSchema(`
  type Student{
    name:String
    age:Int
  }
  type Query {
    hello: String
    name:String
    student:Student
  }
`);

const root = {
    hello: () => 'Hello world!',
    name:()=>{
        return 'zhangbf'
    },
    student:()=>{
        return {
            name:'张三丰',
            age:18
        }
    }
};

const app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
}));
app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));
运行结果

GraphQL 学习

4. 定义参数类型

新建一个 baseType.js文件
const express = require('express');
const graphqlHTTP = require('express-graphql');
const {buildSchema} = require('graphql');

const schema = buildSchema(`
  type Query {
    getClassMates(classNo:Int):[String]
  }
`);

const root = {
    getClassMates({classNo}) {
        const obj = {
            301: ['张三丰', '张翠山', '殷素素'],
            61: ['张大三', '李大四', '王大五'],
        };
        return obj[classNo];
    }
};

const app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
}));
app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));
运行该文件 node baseType.js
在浏览器查看结果,如下

GraphQL 学习

示例二
const express = require('express');
const graphqlHTTP = require('express-graphql');
const {buildSchema} = require('graphql');

const schema = buildSchema(`
  type Student{
    name:String
    sex:String
    age:Int
    grade(number:Int):String
  }
  type Query {
    getClassMates(classNo:Int):[String]
    student(username:String):Student
  }
`);

const root = {
    getClassMates({classNo}) {
        const obj = {
            301: ['张三丰', '张翠山', '殷素素'],
            601: ['张无忌', '赵敏', '周芷若'],
        };
        return obj[classNo];
    },
    student({username}){
        const name=username;
        const sex="男";
        const age=20;
        const grade=({number})=>{
            if(number>60){
                return "及格了"
            }else{
                return "垃圾"
            }
        };

        return {
            name,
            sex,
            age,
            grade
        }

    }
};

const app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
}));
app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));

GraphQL 学习

三、使用GraphQL

1.在客户端访问graphql的接口

1.1 允许静态资源访问目录

app.use(express.static('public'));

GraphQL 学习

1.2 在 public 目录下添加 index.html 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>graphql 客户端访问接口</title>
</head>
<body>
<button onclick="getData()">获取数据</button>
</body>

<script>
    function getData() {
        const query = `
            query Student($username:String,$number:Int){
                student(username:$username){
                    name
                    age
                    sex
                    grade(number:$number)
                }
            }
        `;

        const variables = {username: '张三丰', number: 56};

        fetch('/graphql', {
            method: "POST",
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
            },
            body: JSON.stringify({
                query: query,
                variables: variables
            })
        }).then(res => res.json)
            .then(json => {
                console.log(json);
            })
    }
</script>
</html>

1.3 重新启动

node baseType.js

1.4 查看访问结果

GraphQL 学习

2. 在客户端修改数据

创建一个文件,用于测试 插入数据、更新数据。

2.1 新建一个 mutation.js 文件

创建一个 mutation.js 文件
const express = require('express');
const graphqlHTTP = require('express-graphql');
const {buildSchema} = require('graphql');

const schema = buildSchema(`
    input StudentInput{
        name:String
        age:Int
        sex:String
        grade:Int
    }
    type Student{
        name:String
        age:Int
        sex:String
        grade:Int
    }
    type Mutation{
        createStudent(input:StudentInput):Student
        updateStudent(id:ID!,input:StudentInput):Student
    }
    
    type Query{
        student:[Student]
    }
`);

const fakeDb = {};//数据库对象

const root = {
    student() {
        const arr = [];
        for (const index in fakeDb) {
            arr.push(fakeDb[index]);
        }
        return arr;
    },
    createStudent({input}) {
        //类似保存到数据库
        fakeDb[input.name] = input;
        //返回保存结果
        return fakeDb[input.name];
    },
    updateStudent({id, input}) {
        //保存在一个对象里面
        const updateStudent = Object.assign({}, fakeDb[id], input);
        fakeDb[id] = updateStudent;
        //返回对象
        return updateStudent;
    }
};

const app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
}));
app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));

2.2 执行查看结果

node mutation.js

GraphQL 学习

2.3 认证中间件

创建一个 middleware.js 文件,用于测试
const express = require('express');
const graphqlHTTP = require('express-graphql');
const {buildSchema} = require('graphql');

const schema = buildSchema(`
    input StudentInput{
        name:String
        age:Int
        sex:String
        grade:Int
    }
    type Student{
        name:String
        age:Int
        sex:String
        grade:Int
    }
    type Mutation{
        createStudent(input:StudentInput):Student
        updateStudent(id:ID!,input:StudentInput):Student
    }
    
    type Query{
        student:[Student]
    }
`);

const fakeDb = {};//数据库对象

const root = {
    student() {
        const arr = [];
        for (const index in fakeDb) {
            arr.push(fakeDb[index]);
        }
        return arr;
    },
    createStudent({input}) {
        //类似保存到数据库
        fakeDb[input.name] = input;
        //返回保存结果
        return fakeDb[input.name];
    },
    updateStudent({id, input}) {
        //保存在一个对象里面
        const updateStudent = Object.assign({}, fakeDb[id], input);
        fakeDb[id] = updateStudent;
        //返回对象
        return updateStudent;
    }
};

const app = express();

const middleware = (req, res, next) => {
    if (req.url.indexOf('/graphql') !== -1 && req.headers.cookie.indexOf('auth') === -1) {
        res.send(JSON.stringify({
            error: '您没有权限访问该接口'
        }));

        return false;
    }

    //放行
    next();
};

//注册中间件
app.use(middleware);

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

app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));

GraphQL 学习

添加 auth值

GraphQL 学习

3. 使用ConstructingTypes 类型

为了便于维护,使用 ConstructingTypes 类型

1.创建 constructingTypes.js 测试文件

const express = require('express');
const graphqlHTTP = require('express-graphql');
const graphql = require('graphql');

var StudentType = new graphql.GraphQLObjectType({
    name: "Student",
    fields: {
        name: {type: graphql.GraphQLString},
        age: {type: graphql.GraphQLInt},
        sex: {type: graphql.GraphQLString},
        grade: {type: graphql.GraphQLInt},
    }
});

var queryType = new graphql.GraphQLObjectType({
    name: 'Query',
    fields: {
        student: {
            type: StudentType,
            args: {
                username: {type: graphql.GraphQLString}
            },
            resolve: function (_, {username}) {
                const name = username;
                const sex = '男';
                const age = 18;
                const grade = 20;
                return {
                    name,
                    sex,
                    age,
                    grade
                }
            }
        }
    }
});

var schema = new graphql.GraphQLSchema({query: queryType});


const app = express();

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

app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));
查看运行结果

GraphQL 学习

四.与数据库相结合

1.创建测试数据库 test

在 test数据库下面 创建 student 表

GraphQL 学习

2.在安装mysql插件

在 npmjs.com 网站找 mysql
安装
 npm install mysql2 -S

3. 创建 database.js 测试文件

const express = require('express');
const graphqlHTTP = require('express-graphql');
const {buildSchema} = require('graphql');
const mysql = require('mysql2');

//https://www.npmjs.com/package/mysql2  mysql

//连接数据库
const connection = mysql.createConnection({
    host: 'localhost', //数据库访问地址
    user: 'root', //数据库用户
    password: 'root', //数据库访问密码
    database: 'test' //数据库
});

const schema = buildSchema(`
    input StudentInput{
        name:String
        age:Int
        sex:String
        grade:Int
    }
    type Student{
        name:String
        age:Int
        sex:String
        grade:Int
    }
    type Mutation{
        createStudent(input:StudentInput):Student
        deletedStudent(id:ID!):Boolean
        updateStudent(id:ID!,input:StudentInput):Student
    }
    
    type Query{
        student:[Student]
    }
`);

const root = {
    student() {
        //查询操作
        return new Promise((resolve, reject) => {
            connection.query('select name,sex,age,grade from student', (err, results) => {
                if (err) {
                    console.log(results);
                    console.log('出错了:' + err);
                    return false;
                }
                const arr = [];
                for (let i = 0; i < results.length; i++) {
                    arr.push({
                        name: results[i].name,
                        sex: results[i].sex,
                        age: results[i].age,
                        grade: results[i].grade,
                    })
                }
                resolve(arr);
            })
        });
    },
    createStudent({input}) {
        //保存到数据库
        const data = {
            name: input.name,
            age: input.age,
            sex: input.sex,
            grade: input.grade,
        };

        return new Promise((resolve, reject) => {
            connection.query('insert into student set ?', data, (err,results) => {
                if (err) {
                    console.log(results);
                    console.log('出错了:' + err.message);
                    return false;
                }

                resolve(data);
            });
        });

    },
    updateStudent({id, input}) {

        //更新操作
        const data = input;

        return new Promise((resolve, reject) => {
            connection.query('update student set ? where name=?', [data, id], (err,results) => {
                if (err) {
                    console.log(results);
                    console.log('出错了:' + err.message);
                    return false;
                }
                resolve(data);
            });
        });
    },

    deletedStudent({id}) {

        //删除操作
        return new Promise((resolve,reject)=>{
            connection.query('delete from student where name=?',[id],(err,results)=>{
                if (err) {
                    console.log(results);
                    console.log('出错了:' + err.message);
                    reject(false);
                    return false;
                }
                resolve(true);
            })
        });
    }
};

const app = express();

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

app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));

4.查看演示结果

启动 node database.js

GraphQL 学习

GraphQL 学习

相关推荐