GraphQL

一、GraphQL 是什么?

GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

一个 GraphQL 服务是通过定义类型和类型上的字段来创建的,然后给每个类型上的每个字段提供解析函数。

二、 简单的使用搭建

1、创建或进入一个空目录,在该目录下输入如下命令

npm init -y

2、搭建环境

npm install express graphql express-graphql -S

3、创建文件 helloworld.js

const express = require('express');
const {buildSchema} = require('graphql');
const { graphqlHTTP } = require('express-graphql');
// 定义schema,查询和类型
const schema = buildSchema(`
    type Account {
        name: String
        age: Int
        sex: String
        department: String
    }
    type Query {
        hello: String
        accountName: String
        age: Int
        account: Account
    }
`)
// 定义查询对应的处理器
const root = {
    hello: () => {
        return 'hello world';
    },
    accountName: () => {
        return '张三丰';
    },
    age:()=>{
        return 18;
    },
    account: ()=>{
        return {
            name: '李四光',
            age: 18,
            sex: '男',
            department: '科学院'
        }
    }
}
const app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true
}))
app.listen(3000, ()=>{
    console.log("访问到了");
});

4、运行文件

node helloworld.js

5、浏览器进入 localhost:3000 端口

6、加上后续参数

7、就可以进入 Graphql 界面

三、参数类型与参数传递

1、参数类型

	1.1基本类型:String,Int,Float,Boolean和ID,可以在shema声明的时候直接使用
	1.2类型 代表数组,例如: [int]代表整型数组

2、参数传递

2.1  和js传递参数一样,小括号定义形参,但是注意:参数需要定义类型
2.2 !(叹号)代表参数不能为空
		type Query{
			rollDice(numDice:Int!,numSides:Int) :[Int]
	}

3、核心代码

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

const schema = buildSchema(`
type Query {
        getClassMates(classNo: Int!): [String]
    }
`)
const root = {
    getClassMates({ classNo}) {
        const obj = {
            31: ['张三', '李四', '王五'],
            61: ['张大三', '李大四', '王大五']
        }
        return obj[classNo];
    }
    }


const app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true
}))
app.listen(3000, ()=>{
    console.log("访问到了");
});

自定义类型参数

// 定义schema,查询和类型
const schema = buildSchema(`
    type Account {
        name: String
        age: Int
        sex: String
        department: String
        salary(city: String): Int
    }
    type Query {
        getClassMates(classNo: Int!): [String]
        account(username: String): Account
    }
`)
// 定义查询对应的处理器
const root = {
    getClassMates({ classNo}) {
        const obj = {
            31: ['张三', '李四', '王五'],
            61: ['张大三', '李大四', '王大五']
        }
        return obj[classNo];
    },
    account({ username}) {
        const name = username;
        const sex = 'man';
        const age = 18;
        const department = '开发部';
        const salary = ({city}) => {
            if(city === "北京" || city == "上海" || city == "广州" || city == "深圳") {
                return 10000;
            }
            return 3000;
        }
        return {
            name,
            sex,
            age,
            department,
            salary
        }
    }
}

四、GraphQL Cli

如何在客户端访问GraphQL?

在baseType.js  追加

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

在目录下创建public 文件夹,在文件夹下建立 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <button onclick="getData()">获取数据</button>
</body>
<script>
    function getData() {
        const query = `
        query Account($username: String, $city: String) {
            account(username: $username) {
                name
                age
                sex
                salary(city: $city)
            }
        }
        `
        const variables = {username: '李大四', city: '深圳'}

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

结果截图

五、使用Mutations修改数据

创建mutation.js

const express = require('express');
const {buildSchema} = require('graphql');
const { graphqlHTTP }= require('express-graphql');
// 定义schema,查询和类型, mutation
const schema = buildSchema(`
    input AccountInput {
        name: String
        age: Int
        sex: String
        department: String
    }
    type Account {
        name: String
        age: Int
        sex: String
        department: String
    }
    type Mutation {
        createAccount(input: AccountInput): Account
        updateAccount(id: ID!, input: AccountInput): Account
    }
    type Query {
        accounts: [Account]
    }
`)

const fakeDb = {};

// 定义查询对应的处理器
const root = {
    accounts() {
        var arr = [];
        for(const key in fakeDb) {
            arr.push(fakeDb[key])
        }
        return arr;
    },
    createAccount({ input }) {
        

        // 相当于数据库的保存
        fakeDb[input.name] = input;
        // 返回保存结果
        return fakeDb[input.name];
    },

    updateAccount({ id, input }) {
        // 相当于数据库的更新
        const updatedAccount = Object.assign({}, fakeDb[id], input);
        fakeDb[id] = updatedAccount;
        // 返回保存结果
        return updatedAccount;
    }
}

const app = express();

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

app.listen(3000,()=>{
    console.log("访问到了");
});

六、认证与中间件

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

七、高级Constructing Types(提高可维护性,代码量上升)

1.使用GraphQLObjectType定义Type(类型)

原始代码

// 定义schema,查询和类型
 const schema = buildSchema(`
     type Account {
         name: String
         age: Int
         sex: String
         department: String
     }
    type Query {
        account(username: String): Account
     }
 `)

高级代码

var AccountType = new graphql.GraphQLObjectType({
    name: 'Account',
    fields: {
        name: { type: graphql.GraphQLString },
        age: { type: graphql.GraphQLInt },
        sex: { type: graphql.GraphQLString },
        department: { type: graphql.GraphQLString }
    }
});

2、使用GraphQLObjectType定义query(查询)

原始代码

 const schema = buildSchema(`
     type Account {
         name: String
         age: Int
         sex: String
        department: String
     }
     type Query {
       account(username: String): Account
    }
 `)

高级代码

var queryType = new graphql.GraphQLObjectType({
    name: 'Query',
    fields: {
        account: {
            type: AccountType,
            // `args` describes the arguments that the `user` query accepts
            args: {
                username: { type: graphql.GraphQLString }
            },
            resolve: function (_, { username }) {
                const name = username;
                const sex = 'man';
                const age = 18;
                const department = '开发部';
                return {
                    name,
                    sex,
                    age,
                    department
                }
            }
        }
    }
});

3、创建shema

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值