GraphQL entry

Introduce a .GraphQL

1.1 interface development mode

  • restful
  • GraphQL

1.2 restful interface issues

  • Interface relatively small size, many scenes need to call several times to complete a function
  • Interface extension, maintenance costs high
  • Data format of interfaces can not predict the response, basically the current use json

1.3 GraphQL Overview

GraphQL 是一种用于 API 的查询语言、也是一个满足你数据查询的运行时
是一种接口开发标准、支持常见的服务器开发语言
复制代码

1.4 GrapgQL advantage

  • Accurate access to information needed
  • Access to various resources via a single request
  • The query system by type
  • Powerful debugging tool

II. Started to play

2.1 server

  • Create a project directory server

  • Initialization project npm init -y

  • Create a file entry index.js

  • Installation dependencies

    • Apollo-server-express

    • express

    • graphql

      npm install apollo-server-express body-parser express graphql graphql-tools -S
      复制代码
  • Copy the code to the official case index.js

  • start up

2.2 Client

{
  hello
}
复制代码

III. Development based apolloServer

apolloserver 是一个实现了 GraphQL 规范的框架、可以基于apolloserver 快速开发基于 GraphQL 的服务端接口、并且方便客户端进行接口调用
复制代码

3.1 Development

  • The basic development steps - server
    • Initialization server project
      • Create a project directory
      • Create a file entry
      • Initialize the project
    • Installation depends
    • Defined Types
    • Analytical data
    • Apollo objects instantiated
    • Integrated express and listen port to provide web services

3.2 Object Type Definition Rules

3.2.1 Object Type field defines the

  • GraphQL provides a complete type system, which can constrain the type of data for client server server can use to query
  • By type keywords defined type, after the type is the type of name (custom name)
# 课程类型
type Course {
  cname: String
  score: Float
}

# 学生类型
type Student{
  name: String
  scores:[Course]
}
复制代码
  • Precautions
    • Braces is the field of information objects
    • The property name is customizable
    • The latter type of attribute names scalar type (built-in type)
    • GraphQL use annotation #

3.2.2 Basic parameters

  • Each field on the object types may have zero or more parameters
type Query {
  hello: String
  # 定义字段参数 可以有默认值
  stu(n: Int = 12): Student
}


# 获取参数(通过 resolver 函数的第二个参数获取客户端传递的参数数据)
const resolvers = {
  Query: {
    stu: (obj, args) => {
      console.log(args)
    }
  }
}

# 客户端字段传递
{
  stu(n: 13){
    name
    age
  }
}
复制代码
  • Precautions
    • Parameter can specify a default value, if there is a default value of the parameter is optional
    • The client can acquire data transmitted via the second argument of the function resolvers

3.3.3 built-in type

  • And change the type of query
内置类型中有两个特殊的类型:Query(主要用于查询操作) 和 Mutation(主要用于变更操作 -- 增、删、改 )

每一个GraphQL 服务有一个 Query 类型、也可能有一个 mutation 类型、这两个类型本质上也是对象类型、唯一的区别就是他们作为客户端访问的入口
复制代码
  • Scalar type - indicates the basic field data, query data representing leaf nodes
    • Int
    • Float
    • String
    • Booleab
    • A unique identifier ID, generates a random string, you do not need to recognize
  • Enumerated type - is a special scalar type restrictions enumerated in a particular set of values ​​within the alternative
enmu Fovour {
	SWIMING
	GODING
	SINGING
}
复制代码

As defined above represents only one of the three values ​​acquired, obtaining values ​​of other types is not possible

  • And a list of non-empty
    • [] Indicates the list
    • ! Exclamation mark represents a non-empty
type Student{
	name: String!
	scores:[Score]!
}
复制代码

myField: [! String] represents an array itself may be empty, but it can not have any member of null values

myField:! [String] represents an array itself may not be empty, but it can contain null values ​​members

3.3.4 Input Type

Parameters can also be a complex type, mainly for changing mutation scene - need to pass client input type

  # 输入类型
  input UserInfo{
    name: String
    pwd: String
  }

  #用户类型
  type User {
    id: ID
    name: String
    pwd: String
  }
复制代码

input data type definitions mutation, can be passed by the client for receiving

# 变更类型
type Mutation{
	addUserByInput(userInput: UserInfo): User
}
复制代码
# 处理客户端传递的input参数
const resolvers = {
  Query: {
    hello: () => 'Hello world!'
  },
  Mutation: {
    addUserByInput: (obj, args) => {
      return {
        id: uuid(),
        name: args.userInput.name,
        pwd: args.userInput.pwd
      }
    }
  }
};
复制代码
# 客户端查询操作
mutation {
	addUserByInput(userInput: {
		name: 'nordon',
		pwd: '123123'
	}){
		id
		name
	}
}
复制代码
  • Precautions
    • input type is mainly used to change data transfer operation

3.3 Detailed data parsing rules

### 3.3.1 resolver function parameter usage

resolvers for providing the actual data to a type field

  • resolver function parameters
    • parent On one subject, if the field belongs to the root node query types are usually not used
    • args We can provide incoming query parameters in GrapgQL
    • contextIt will be available to all parser, and holds important contextual information. Such as the current logged in user, database access objects
    • info Save a query value associated with the current field-specific information as well as detailed information schema
  Mutation: {
    addUserByInput: (parent, args, context, info) => {
      // parent 当前字段的父级对象 -- Query 中的 hello 相当于根节点,例如查学生中的 name、age 就是子节点
      // args 客户端传递过来的参数
      // context 可以用于操作数据源
      // info 不怎么用
      return {
        id: uuid(),
        name: args.userInput.name,
        pwd: args.userInput.pwd
      }
    }
  }
复制代码
  • Parent parameter usage
// 类型定义
type Student {
	name: String
	age: Int
	favour: String
}

// 数据解析
const resolvers = {
  Student: {
    // 提供字段的 resolver 函数、如果不提供会默认生成
    name: (parent) => {
      // return 'wangyao' 会覆盖父节点的 name
      return parent.name
    },
    favour: (parent) => {
      if(parent.favour === 'swimming'){
        return '洗澡'
      }else{
        return parent.favour
      }
    }
  },
  Query: {
    hello: () => 'Hello world!',
    stu: (parent) => {
      return {
        name: 'nordon',
        age: 18,
        favour: 'swimming'
      }
    }
  },
};
复制代码
  • Precautions
    • May be acquired by the parent object is the first parameter function parent resolver
    • If the field type is a scalar type, there will be a default resolver function
    • Default resolver function returns the field data parent objects

3.3.2 resolver docking function data source

More convenient function through the abutting context data source (database, files, third party interface), including asynchronous operation

  • Basic usage context
// context 可以用于获取数据源对象
const context = () => {
	return {
		db: 'dbObj'
	}
}

const server = new ApolloServer({
	typeDefs,
	resolvers,
	context
})
复制代码
// 在 resolver 函数中可以通过 context 对象操作数据源
const resolvers = {
	Query: {
		hello: (parent, args, context) => {
			// 通过 context 可以获取数据源操作对象
			let ret = context.db
		}
	}
}
复制代码
  • Reads the file data service module
// db.js 代码:从文件中读取数据、本质上与从数据库中读取数据类型、多可以异步操作
const path = require('path')
const fs = require('fs')

module.exports.getData = () => {
	const dataPath = path.join(__dirname, 'data.json')
	
	return new Promise((resolve, reject) => {
		fs.readFile(dataPage, (err, data) => {
			if(err){
				reject(err)
			}
			
			resolve(data.toString())
		})
	})
}

// data.json 提供数据源
[{
  "name": "nordon",
  "age": 18
},{
  "name": "wangyao",
  "age": 22
},{
  "name": "bing",
  "age": 23
}]
复制代码
  • Operated by a data source from context object
// 从文件中读取数据作为数据源、 db.getData() 返回 Promise 实例对象
const db = require('./db.js')

const typeDefs = gql`
  # 学生
  type Student {
    name: String
    age: Int
  }

  # 查询类型
  type Query {
    hello: [Student!]!
  }
`;

const context = ({req}) => {
	return {
		db: db
	}
}

const resolvers = {
	Query: {
		hello: async (parent, args, context, info) => {
			const ret = await context.db.getData()
			return JSON.parse(ret)
		}
	}
}


const server = new ApolloServer({
	typeDefs,
	resolvers,
	context
})
复制代码
  • Precautions
    • The main object provides a context parameter relating to a data source, to facilitate data manipulation (data acquisition and change)
  • Client Development Portal GraphQL client development

Reference website

grapgQL official website

apolloserver official website

Guess you like

Origin blog.csdn.net/weixin_34126557/article/details/91364619