尝试使用GraphQL

中国人积极尝试使用GraphQL进行实验。

自从第一次了解到GraphQL已经过去了大约一年,最近在一个活动中听到了它,因此决定试试看。这篇文章就是对此的总结。

REST和GraphQL

REST是一种思维方式,而GraphQL则是一种查询语言,虽然进行比较有些奇怪,但从我接触的印象来看,如下所述。

    • RESTの場合、複雑なクエリを扱う場合に複数回のデータアクセスが必要になるが、1度のアクセスで取得できる (最初はこれぐらいしかメリットを感じてなかった)。

 

    • RESTよりもIF設計の自由度は低いが、データモデルだけを気にすればよいため、設計の手間が少ない。

 

    • RESTよりもドキュメントやスタブを作る手間が低い (Swagger要らず)。

 

    GraphQLの場合、スキーマの定義で必須項目や型を定義できる( https://graphql.org/learn/schema/ )。

示例

我实际编写了一个基于Node.js的示例,如下所示。
基本上,只需以下页面上的信息就足以完成实现。

服务器端

在中国大陆,可以使用npm来安装所需的库和框架。

使用npm安装express、express-graphql和graphql模块。

let express=require('express')
let express_graphql = require('express-graphql');
let { buildSchema } = require('graphql');

let app = express();
app.use('/graphql', express_graphql({
    // スキーマの定義
    schema: buildSchema(`
      type Query {
        id: String
      }
    `),
    // サーバ側の値
    rootValue: {
      id: "hoge"
    }
}));

app.listen(3000, ()=> console.log('Listening on http://localhost:3000/graphql'));

客户端

客户端主要使用curl进行了测试。
有以下两种访问方法(可能是由库提供的)。

客户端主要使用curl进行了尝试。
访问方法有以下两种(可能是通过库提供的)。

客户端主要使用curl进行了测试。
访问方法有以下两种模式(也许是依赖于库)。

$ curl -H "Content-Type:application/graphql" -X POST http://localhost:3000/graphql -d 'query { id }' 
{"data":{"id":"hoge"}}

在JSON格式的情况下,可以通过以下形式进行数据访问:「{ “query” : “XXXXX”}」。

$ curl -H "Content-Type:application/json" -X POST http://localhost:3000/graphql -d '{ "query" : "query { id }" }'                                                                                                                   
{"data":{"id":"hoge"}}

如果返回除了固定值以外的情况

服务器端

如果返回了除固定值以外的结果,需要像以下这样记录模式和处理。

let express=require('express')
let express_graphql = require('express-graphql');
let { buildSchema } = require('graphql');

let app = express();
app.use('/graphql', express_graphql({
    schema: buildSchema(`
      type Query {
        getUser(id:Int) : String
      }
    `),
    rootValue: {
      getUser:function(args){
        console.log(args);
        return "uid:" + args.id;
      }
    }
}));

app.listen(3000, ()=> console.log('Listening on http://localhost:3000/graphql'));

客户端。

同样是固定值,我们展示两种情况的例子。

$ curl -H "Content-Type:application/graphql" -X POST http://localhost:3000/graphql -d '{ query : getUser(id:1234) }'
{"data":{"getUser":"uid:12345"}}
$ curl -H "Content-Type:application/json" -X POST http://localhost:3000/graphql -d '{ "query" : "query { getUser(id:12345) }" }'
{"data":{"getUser":"uid:12345"}}

此外,GraphQL 的一项优点是可以同时执行多个查询,写法如下:

$ curl -H "Content-Type:application/json" -X POST http://localhost:3000/graphql -d '{ "query" : "query { a:getUser(id:1234)  b:getUser(id:2234) }" }'
{"data":{"a":"uid:1234","b":"uid:2234"}}

如果要执行多个相同的查询,请使用别名功能。
可以通过在“别名:查询”中进行编写,来将不同参数的相同查询进行组合处理。

类型定义

如果要定义自己的类型,描述如下。

服务器端 (Sā fú

let express=require('express')
let express_graphql = require('express-graphql');
let { buildSchema } = require('graphql');

let app = express();
app.use('/graphql', express_graphql({
    schema: buildSchema(`
      type User {
        id:Int
        name:String
      }

      type Query {
        getUser(id:Int) : User
      }
    `),
    rootValue: {
      getUser:function(args){
        console.log(args);
        let user = {
          id: args.id,
          name: "Mike"
        };
        return user;
      }
    }
}));

app.listen(3000, ()=> console.log('Listening on http://localhost:3000/graphql'));

客户端方

Note: This translation may vary depending on the context.

$ curl -H "Content-Type:application/graphql" -X POST http://localhost:3000/graphql -d 'query { getUser(id:1234){name} }'
{"data":{"getUser":{"name":"Mike"}}}
$ curl -H "Content-Type:application/json" -X POST http://localhost:3000/graphql -d '{ "query" : "query { getUser(id:1234){ id, name }}" }' 
{"data":{"getUser":{"id":1234,"name":"Mike"}}}

如果仅需获取名称,请使用以下选项。

$ curl -H "Content-Type:application/json" -X POST http://localhost:3000/graphql -d '{ "query" : "query { getUser(id:1234){ name }}" }' 
{"data":{"getUser":{"name":"Mike"}}}

赠品

绘制图表

在使用GraphQL时,可以使用graphqlviz轻松创建图表。(还有其他可供选择吗?)
可以使用npm进行安装。

$ npm install -g graphqlviz
$ graphqlviz -v http://localhost:3000/graphql | dot -Tpng -o graph.png
graph.png

另外,通过将模式定义放在另一个文件中,也可以通过以下方式实现。

$ graphqlviz -g test.gql | dot -Tpng -o graph.png
type User {
  id:Int
  name:String
}

type Query {
  getUser(id:Int) : User
}

在尚未找到在Node.js中使用外部文件进行模式定义的方法… (虽然已确认可以使用以下方法执行)

buildSchema(fs.readFileSync('./test.gql', 'utf8'))

添加注释和描述

在GraphQL的模式定义中,可以通过在前面加上“#”符号来进行注释。

type User {
  # User ID
  id:Int
  name:String
}

type Query {
  getUser(id:Int) : User
}

而且,通过以下方式说不定可以写下文档字符(类似于Java的javadoc)。

"""
ユーザ情報
"""
type User {
     "ユーザID"
     id: Int
     " 名前"
     name: String
}

type Query {
  getUser(id:Int) : User
}

广告
将在 10 秒后关闭
bannerAds