美文网首页GraphQL
GraphQL学习与实践2(类型、传参与构造函数类型)

GraphQL学习与实践2(类型、传参与构造函数类型)

作者: 小生叫不才 | 来源:发表于2019-10-27 15:19 被阅读0次

在上一节的已经成功搭建了一个hello world的基础上,这里来说一下GraphQL类型相关及其一些实践操作、搭建一个schema等。

Type System

几乎任何一门语言,都是具有类型的。GraphQL常用的类型有:

  • 标量类型
  • 列表和非空
  • 枚举类型
  • 对象类型
  • 接口
  • 联合类型
  • 输入类型
    ...

标量类型
GraphQL 自带一组默认标量类型:

  • Int:有符号 32 位整数。
  • Float:有符号双精度浮点值。
  • String:UTF‐8 的字符序列。
  • Boolean:true或false。
  • ID:ID 标量类型表示一个唯一标识符,通常用以重新获取对象或者作为缓存中的键。ID 类型使用和 String 一样的方式序列化;

列表和非空
默认情况下,每种类型都会返回null作为任何标量。与此相对的可以使用感叹号(!)表示非空类型。例如:String!表示非空字符串。
和大多数语言类似的,使用中括号来代表列表,例如:[Int]表示一个整型的列表。

枚举类型
枚举类型是一种特殊的标量,它限制在一个特殊的可选值集合内。例如:

enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}

这表示了无论在schema中哪里使用了Episode ,其返回值肯定是NEWHOPE、EMPIRE、JEDI三个值其中一个。(注意,各种语言实现的 GraphQL 服务会有其独特的枚举处理方式。但对于JavaScript 在ES5中没有支持,些枚举值可能就被内部映射成整数值。但这都是内部的细节,并不会影响使用。)

对象类型
GraphQL schema 中的最基本的组件是对象类型。它就表示你可以从服务上获取到什么类型的对象,以及这个对象有什么字段。例如:

type Character {
  name: String!
  appearsIn: [Episode!]!
}

Character 是一个 GraphQL 对象类型,表示其是一个拥有一些字段的类型。

实例:修改test2-express.js中的hello world的demo为如下:

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(` 
    type objName {
        name:String
    }
    type Query {
        hello:objName
    }
`);
// The root provides the top-level API endpoints
var root = {
    hello: () => { return { name: 'hello world' } },
}
var app = express();
app.use('/graphql', graphqlHTTP({ schema: schema, rootValue: root, graphiql: true, }));
app.listen(4000); console.log('Running a GraphQL API server at localhost:4000/graphql');

执行node test2-express.js。打开浏览器的调试工具,输入:

{
  hello {
    name
  }
}

如图:


在这里插入图片描述

上面把hello中的String类型改为了对象类型的objName,objName中带有String类型的name属性。

传参

这里以官网的例子为例:

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
         rollDice(numDice: Int!, numSides: Int): [Int] }
         `
);
// The root provides a resolver function for each API endpoint
var root = {
    rollDice: function ({ numDice, numSides }) {
        var output = [];
        for (var i = 0; i < numDice; i++) {
            output.push(1 + Math.floor(Math.random() * (numSides || 6)));
        }
        return output;
    }
};
var app = express();
app.use('/graphql', graphqlHTTP({ schema: schema, rootValue: root, graphiql: true, }));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');

执行node test5-args.js。打开浏览器的调试工具,输入:

{
  rollDice(numDice:3,numSides:6)
}

如图:


在这里插入图片描述

模拟客户端发送请求?
这里以RESTClient为工具进行模拟客户端发送请求,如图:


在这里插入图片描述
body:{"query":"{rollDice(numDice:3,numSides:6)}"}

来自官网对于对象类型的例子,新建一个test6-object.js文件:

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type RandomDie {
         numSides: Int! 
         rollOnce: Int! 
         roll(numRolls: Int!): [Int] 
        } 
    type Query { 
        getDie(numSides: Int): RandomDie 
    } `
);
// This class implements the RandomDie GraphQL type
class RandomDie {
    constructor(numSides) {
        this.numSides = numSides;
    }
    rollOnce() {
        return 1 + Math.floor(Math.random() * this.numSides);
    }
    roll({ numRolls }) {
        var output = [];
        for (var i = 0; i < numRolls; i++) {
            output.push(this.rollOnce());
        }
        return output;
    }
}
// The root provides the top-level API endpoints
var root = {
    getDie: function ({ numSides }) {
        return new RandomDie(numSides || 6);
    }
}
var app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');

执行node test6-object.js。打开浏览器的调试工具,输入:

{
  getDie(numSides:3){
    roll(numRolls:2)
    rollOnce
  }
}

如图:


在这里插入图片描述

在上面的例子中,看到了是自定义了一个类型RandomDie,在类中定义有三个属性,分别为:numSides 、rollOnce、roll。在上例中就显示了两个方法的调用。如果此时需要显示numSides属性的话,只需要加上numSides的属性就可以获取到对应的返回,如图:


在这里插入图片描述

构造类型

对于许多应用程序,您可以在应用程序启动时定义固定模式,并使用GraphQL模式语言对其进行定义。在某些情况下,以构造类型是很有用的。
而且,使用GraphQLSchema构造类型来构建架构,可以把对应的schema作为单独的对象创建,这样就方便我们的项目目录管理了。
直接上官网的例子来对比说明,
过往的方式:

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
var schema = buildSchema(`
 type User {
      id: String 
      name: String 
    } 
    type Query {
         user(id: String): User 
        } `
);
// Maps id to User object
var fakeDatabase = {
    'a': {
        id: 'a',
        name: 'alice',
    },
    'b': {
        id: 'b',
        name: 'bob',
    },
};
var root = {
    user: function ({ id }) {
        return fakeDatabase[id];
    }
};
var app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');

执行node test6-object.js。打开浏览器的调试工具,输入:

{
  user(id:"a"){
    name,
    id
  }
}

如图:


在这里插入图片描述

使用GraphQL Schema来使用相同的API,见下:

var express = require('express');
var graphqlHTTP = require('express-graphql');
var graphql = require('graphql');
// Maps id to User object
var fakeDatabase = {
    'a': {
        id: 'a',
        name: 'alice',
    },
    'b': {
        id: 'b',
        name: 'bob',
    },
};
// Define the User type
var userType = new graphql.GraphQLObjectType({
    name: 'User',
    fields: {
        id: {
            type: graphql.GraphQLString
        },
        name: {
            type: graphql.GraphQLString
        },
    }
});
// Define the Query type
var queryType = new graphql.GraphQLObjectType({
    name: 'Query',
    fields: {
        user: {
            type: userType,
            // `args` describes the arguments that the `user` query accepts 
            args: {
                id: {
                    type: graphql.GraphQLString
                }
            },
            resolve: function (_, { id }) {
                return fakeDatabase[id];
            }
        }
    }
});

var schema = new graphql.GraphQLSchema({ query: queryType });
var app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');

对比一下buildSchema和GraphQLSchema的创建方式,可以明显的发现使用GraphQLSchema的方式其定义的类型和原来的buildSchema方式的类型不一样了,并且GraphQLSchema更接近OOP的面向对象的思想。


在这里插入图片描述 在这里插入图片描述

两者区别在于:

区别 buildSchema GraphQLSchema
参数类型 字符串 对象
类名 type 字符后面 参数对象的 name 属性
属性定义 定义在类型后,键值对形式 定义在参数对象 fields 属性中,值为对象,每个属性名为键名,值也是对象

同样GraphQLSchema 也有其对应的类型,例如:
GraphQLEnumType、GraphQLFloat、GraphQLID。GraphQLInputObjectType。GraphQLInt、GraphQLInterfaceType、GraphQLList、GraphQLNonNull等等。
具体可以参考:https://graphql.org.cn/graphql-js/type.html

更多:

GraphQL学习与实践1(入门介绍)
GraphQL学习与实践2(类型、传参与构造函数类型)
GraphQL学习与实践3(Mutations And Input Types)

相关文章

  • GraphQL学习与实践2(类型、传参与构造函数类型)

    在上一节的已经成功搭建了一个hello world的基础上,这里来说一下GraphQL类型相关及其一些实践操作、搭...

  • 构造函数注意事项及构造函数创建对象存在问题

    01 构造函数内部设置方法(函数传值)函数传值:可以把构造函数的对象方法抽取为参数 02 对象类型 检查对象的类型...

  • 面向对象02-构造函数注意事项

    构造函数注意事项 01 函数传值 函数传值:可以将对象的方法作为参数传递 代码示例 02 类型判断 类型判断:判断...

  • 继承

    ES5的继承 1、构造函数实现继承 其基本思想为:在子类型的构造函数中调用超类型构造函数。 优点:1.可以向超类传...

  • 05.Object函数

    JavaScript函数是引用类型(对象类型),所以Function函数也是对象 2."Function构造函数"...

  • C语言第11天

    函数类型并且讲解 主函数与调用函数, 1.return 与主函数的类型匹配。 2.定义函数: 3.行参与实参;(对...

  • 类型转换

    用转换构造函数进行类型转换 主要用于其它类型到本类类型的转化。 转换构造函数格式 特点转换构造函数,本质是一个构造...

  • 面向对象(三)构造函数注意事项

    构造函数注意事项 01函数传值 02对象的类型(判断) 03构造器属性(获取) 04函数调用 05this 构造函...

  • C++类型转换函数与类型转换构造函数

    类型转换函数 将一个类型转换成另一个类型的函数。 类型转换构造函数 使用另外的类作为构造函数参数来构造类的对象,这...

  • c++类型转换构造函数

    类型转换构造函数 概念 定义类型转换构造函数的目的是实现类型的自动转化 只有一个参数,而且不是复制构造函数的构造函...

网友评论

    本文标题:GraphQL学习与实践2(类型、传参与构造函数类型)

    本文链接:https://www.haomeiwen.com/subject/iczpvctx.html