GraphQL初探

项目地址:https://github.com/kongpingfan/frontend/tree/master/GraphQL

运行:

npm install
npm run dev

什么是GraphQL

GraphQL可以更高效的设计和使用API,它是REST的替代品,它具有以下优点:

  • 只获取到想获取的内容。使用REST,通常获取的信息会过载,需要提取出有用的字段。
  • 强类型(strongly-typed),在执行前可以做检查。

graphql的官网:https://graphql.org/

Getting started

学习GraphQL,需要有GraphQL的服务端。

可以使用Graphpack,它不需要进行配置:

https://github.com/glennreyes/graphpack

创建一个文件夹,名叫 graphql-server。进行文件夹,进行npm初始化:

npm init -y

安装graphpack:

npm install --save-dev graphpack

安装完后,在package.json中添加:

"scripts": {
    "dev": "graphpack",
    "build": "graphpack build"
}

创建一个src文件夹,里面新建三个文件:

src
  |--db.js
  |--resolvers.js
  |--schema.graphql

schema.graphql

type Query {
  hello: String
}

resolvers.js:

import { users } from "./db";

const resolvers = {
  Query: {
    hello: () => "Hello World!"
  }
};

export default resolvers;

db.js:

export let users = [
  { id: 1, name: "John Doe", email: "john@gmail.com", age: 22 },
  { id: 2, name: "Jane Doe", email: "jane@gmail.com", age: 23 }
];

db.js只是为了模拟真实数据库的数据。


运行npm run dev:

image-20190414095315398

GraphQL有自己的语法格式叫做Schema Definition Language (SDL)

类型

类型(types)是GraphQL最重要的特性之一。例如,创建一个User类型,它可能有name,email,age等字段。

现在将schema.graphql改成这样:

type User {
  id: ID!
  name: String!
  email: String!
  age: Int
}
  • 每行最后的!表示非空(non-nullable)。 只有age字段允许为空

GraphQL中,主要有三个概念:

  1. queries — 从服务端获取数据(查询).
  2. mutations — 更新数据到服务器并获取最新数据(创建、更新、删除)
  3. subscriptions — 维护与服务器的实时连接.

Queries

schema.graphql中添加:

type Query {
  users: [User!]!
}
  • users查询会返回Users数组,并不允许为空

也可以查询指定的user:

type Query {
  users: [User!]!
  user(id: ID!): User!
}
  • 需要传入ID来查询特定user

那从哪里获取数据呢?这就是resolvers.js做的事情,它告诉GraphQL数据源在哪。

resolvers.js更新为:

import { users } from "./db";

const resolvers = {
  Query: {
    user: (parent, { id }, context, info) => {
      return users.find(user => user.id === id);
    },
    users: (parent, args, context, info) => {
      return users;
    }
  }
};

export default resolvers;
  • user函数里,传入id参数,返回该用户。

  • users函数,返回所有的user。

访问localhost:4000,并输入下面查询语句:

query {
  users {
    id
    name
    email
    age
  }
}

返回结果如下:

{
  "data": {
    "users": [
      {
        "id": "1",
        "name": "John Doe",
        "email": "john@gmail.com",
        "age": 22
      },
      {
        "id": "2",
        "name": "Jane Doe",
        "email": "jane@gmail.com",
        "age": 23
      }
    ]
  }
}

如果想查询特定用户:

query {
  user(id: 1) {
    id
    name
    email
    age
  }
}

但是查询出错。

Mutations

更新schema.graphql:

type Mutation {
  createUser(id: ID!, name: String!, email: String!, age: Int): User!
  updateUser(id: ID!, name: String, email: String, age: Int): User!
  deleteUser(id: ID!): User!
}

更新resolver.js:

Mutation: {
    createUser: (parent, { id, name, email, age }, context, info) => {
      const newUser = { id, name, email, age };

      users.push(newUser);

      return newUser;
    },
    updateUser: (parent, { id, name, email, age }, context, info) => {
      let newUser = users.find(user => user.id === id);

      newUser.name = name;
      newUser.email = email;
      newUser.age = age;

      return newUser;
    },
    deleteUser: (parent, { id }, context, info) => {
      const userIndex = users.findIndex(user => user.id === id);

      if (userIndex === -1) throw new Error("User not found.");

      const deletedUsers = users.splice(userIndex, 1);

      return deletedUsers[0];
    }
  }

localhost:4000测试:

mutation {
  createUser(id: 3, name: "Robert", email: "robert@gmail.com", age: 21) {
    id
    name
    email
    age
  }
}

返回:

{
  "data": {
    "createUser": {
      "id": "3",
      "name": "Robert",
      "email": "robert@gmail.com",
      "age": 21
    }
  }
}

删除操作:

mutation{
  deleteUser(id: 3){
    id
    name
    email
    age
  }
}

Subscriptions

当服务端产生一个事件时,服务端会将对应数据发送给客户端。通过这种订阅机制,应用可以确保是实时更新的。

例如:

subscription {
  users {
    id
    name
    email
    age
  }
}

它和query长的有点像,但是工作机制完全不同。

关于subscription更多的内容:https://hackernoon.com/from-zero-to-graphql-subscriptions-416b9e0284f3

Conclusion

它最终会替代`REST

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值