1. 安装

这里没使用apollo来搭建graphql,所以配置比较麻烦些。现在使用apollo来搭建graphql很主流,apollo帮助我们减少编写这些配置graphql的代码

  • 不同框架安装不同的包,比如koa的话,安装koa-graphql,express安装express-graphql

2. 初识demo

  1. import Koa from 'koa';
  2. import Router from 'koa-router';
  3. import graphqlHTTP from 'koa-graphql';
  4. import { buildSchema } from 'graphql';
  5. const app = new Koa();
  6. const router = new Router();
  7. // 定义类型 type Query表示查询, type Mutation表示修改
  8. const schema = buildSchema(`
  9. type Query {
  10. hello: String // 定义了一个查询的变量,和返回的类型
  11. }
  12. `);
  13. ==========================================================
  14. // 当用户在localhost:5000/graphql页面里输入下面这样
  15. query {
  16. hello
  17. }
  18. // 返回值如下
  19. {
  20. "data": {
  21. "hello": "Hello World"
  22. }
  23. }
  24. ==========================================================
  25. // rootValue类似控制器,比如这里上面schema里定义查询hello
  26. // 那么当用户在/graphql这个页面里查询hello字段时,服务器做的相应操作
  27. // 就在这里写
  28. const rootValue = {
  29. hello: () => `Hello World`,
  30. };
  31. router.all(
  32. '/graphql',
  33. graphqlHTTP({
  34. schema,
  35. rootValue,
  36. graphiql: true,
  37. })
  38. );
  39. app.use(router.routes(), router.allowedMethods());
  40. const PORT = process.env.PORT || 5000;
  41. app.listen(PORT, () => console.log(`server started at ${PORT}`));

3. 自定义类型

  1. // 定义类型 type Query表示查询, type Mutation表示修改
  2. const schema = buildSchema(`
  3. type User {
  4. id: ID! // ! ID一定存在
  5. name: String
  6. age: Int
  7. }
  8. type Query {
  9. user: User
  10. }
  11. `);
  12. // rootValue类似控制器,比如这里上面schema里定义查询hello
  13. // 那么当用户在/graphql这个页面里查询hello字段时,服务器做的相应操作
  14. // 就在这里写
  15. const rootValue = {
  16. user: () => ({
  17. id: nanoid(),
  18. name: 'Yoooo',
  19. age: 18,
  20. }),
  21. };

4. 简单拆分文件

把schema拆分到单独的文件里

在根目录新建schema.js

index.js 需要修改下

  1. import Koa from 'koa';
  2. import Router from 'koa-router';
  3. import graphqlHTTP from 'koa-graphql';
  4. import schema from './schema';
  5. const app = new Koa();
  6. const router = new Router();
  7. router.all(
  8. '/graphql',
  9. graphqlHTTP({
  10. schema,
  11. graphiql: true,
  12. })
  13. );
  14. app.use(router.routes(), router.allowedMethods());
  15. const PORT = process.env.PORT || 5000;
  16. app.listen(PORT, () => console.log(`server started at ${PORT}`));

schema.js

  • makeExecutableSchema作用是把类型和控制器糅合在一起,形成一个schema ```javascript import { makeExecutableSchema } from ‘graphql-tools’; import { nanoid } from ‘nanoid’;

const typeDefs = ` type User { id: ID! name: String age: Int }

type Query { user: User } `;

const resolvers = { Query: { user: () => ({ id: nanoid(), name: ‘Yoooo’, age: 12, }), }, };

// makeExecutableSchema作用是把类型和控制器糅合在一起,形成一个schema export default makeExecutableSchema({ typeDefs, resolvers, });

  1. ---
  2. <a name="9BG6s"></a>
  3. ## 5. 完全拆分
  4. > type, resolver也分开
  5. 目录:<br />index.js<br />db.js<br />schema.js<br />typeDefs
  6. - userType.graphql
  7. resolvers
  8. - userResolver.js
  9. **index.js**
  10. ```javascript
  11. import Koa from 'koa';
  12. import Router from 'koa-router';
  13. import graphqlHTTP from 'koa-graphql';
  14. import schema from './schema';
  15. const app = new Koa();
  16. const router = new Router();
  17. router.all(
  18. '/graphql',
  19. graphqlHTTP({
  20. schema,
  21. graphiql: true,
  22. })
  23. );
  24. app.use(router.routes(), router.allowedMethods());
  25. const PORT = process.env.PORT || 5000;
  26. app.listen(PORT, () => console.log(`server started at ${PORT}`));

db.js

  1. const db = {
  2. users: [],
  3. };
  4. export default {
  5. getData: () => db,
  6. setData: (key, value) => {
  7. db[key] = value;
  8. return db;
  9. },
  10. };

schema.js

  1. import {
  2. makeExecutableSchema,
  3. mergeTypeDefs,
  4. loadFilesSync,
  5. mergeResolvers,
  6. } from 'graphql-tools';
  7. import { nanoid } from 'nanoid';
  8. const typeDefs = mergeTypeDefs(loadFilesSync('./typeDefs'), { all: true });
  9. const resolvers = mergeResolvers(loadFilesSync('./resolvers'));
  10. // makeExecutableSchema作用是把类型和控制器糅合在一起,形成一个schema
  11. export default makeExecutableSchema({
  12. typeDefs,
  13. resolvers,
  14. });

typeDefs/userType.graphql

  1. type User {
  2. id: ID!
  3. name: String
  4. age: Int
  5. }
  6. type Query {
  7. userList: [User]
  8. }
  9. type Mutation {
  10. createUser(name: String, age: Int): User
  11. }

resolvers/userResolver.js

  1. import { nanoid } from 'nanoid';
  2. import UserModel from '../models/userModel';
  3. export default {
  4. Query: {
  5. userList: () => UserModel.getUserList(),
  6. },
  7. Mutation: {
  8. createUser: (parent, args) => {
  9. const user = new UserModel({
  10. name: args.name,
  11. age: args.age,
  12. }).create();
  13. return user;
  14. },
  15. },
  16. };

6. GraphQL VS Restful

image.png

  • 相对于restful 很多个接口,GraphQL只有一个end point,就是/graphql
  • express-graphql, apollo 这些包用来帮我们parse incoming graphql requery
  • How are Schemas and Resolvers connected?
    • The express-graphql package does that