GraphQL Mesh是为了解决什么问题而创建的?~ 通过GraphQL将Qiita API包装起来来深入理解GraphQL Mesh ~

image.png

GraphQL Mesh 是什么?

GraphQL Mesh 在 The Guild 宣布发表了。

? GraphQL Mesh – 任意查询,随时随地运行 ?

? 我非常自豪地宣布我们的新开源库 – GraphQL Mesh!使用 #GraphQL 进行查询:
? openapi/Swagger
? gRPC
? SOAP
? SQL
? GraphQL
? 更多!
无需修改源代码!
线程 1/5 pic.twitter.com/xo0G5smUwp— Urigo (@UriGoldshtein) March 23, 2020

GraphQL Mesh 是一个作为与现有后端 API 服务(如 REST API 和 gRPC)连接的代理的功能。
GraphQL Mesh 被设计成使开发人员能够通过 GraphQL 查询轻松访问使用其他 API 规范(如 gRPC、OpenAPI、Swagger、oData、SOAP、GraphQL 等)描述的服务。

以前,为了实现GraphQL代理,需要对后端API服务进行以下操作。

    • その API 仕様を読み解き、

 

    • GraphQL サーバを構築し、

 

    スキーマ、リゾルバ、バックエンド API との通信処理を実装する

我为了实现一个包装多个后端API的GraphQL服务器耗费了大量的努力。

当然,像 openapi-to-graphql 这样的工具可以将 OpenAPI 定义转换为 GraphQL 模式,还有像 graphql-tools 这样根据模式定义构建模拟服务器的工具,已经出现了。

新出现的 GraphQL Mesh 是一种革命性的工具。只要有后端 API 的 API 规范,就可以获得一个可以立即执行 GraphQL 查询的 GraphQL 代理来访问该后端 API。

本篇文章将介绍GraphQL Mesh的简单使用方法和架构设计模式。

※ 本篇文章参考自这篇文章。

用法

假设存在使用OpenAPI编写的REST API服务作为后端,我们将使用GraphQL Mesh构建代理服务器。本次将使用Qiita API作为后端API。

1. 安装

GraphQL Mesh 需要将几个核心库组合安装。

$ yarn add graphql \
           @graphql-mesh/runtime \
           @graphql-mesh/cli \
           @graphql-mesh/openapi

截止至3月25日,可使用的API(以及计划中的API)如下所示。

PackageStatusSupported Spec@graphql-mesh/graphqlAvailableGraphQL endpoint (schema-stitching, based on graphql-tools-fork)@graphql-mesh/federationWIPApollo Federation services@graphql-mesh/openapiAvailableSwagger, OpenAPI 2/3 (based on openapi-to-graphql)@graphql-mesh/json-schemaAvailableJSON schema structure for request/response@graphql-mesh/postgraphileAvailablePostgres database schema@graphql-mesh/grpcAvailablegRPC and protobuf schemas@graphql-mesh/soapAvailableSOAP specification@graphql-mesh/mongooseAvailableMongoose schema wrapper based on graphql-compose-mongoose@graphql-mesh/odataWIPOData specification

2. 在设定文件中描述后端 API 的 API 规范

然后,我们创建一个名为.meshrc.yaml的文件,并描述后端API的API规范。在这个例子中,我们将使用OpenAPI。此外,我们还支持gRPC,oData,SOAP,GraphQL等其他协议。.meshrc.yaml文件应放置在项目的根目录中。

sources:
  - name: Qiita
    handler:
      openapi:
        source: ./qiita.openapi.yaml

QiitaAPI的OpenAPI定义中的.qiita.openapi.yaml如下所示。

Qiita API的规范(OpenAPI)swagger: “2.0”

info:
version: 0.0.1
title: Qiita API

host: “qiita.com”

basePath: “/api/v2”

schemes:
– https

consumes:
– application/json

produces:
– application/json

paths:
“/tags/{tagId}/items”:
get:
parameters:
– in: path
name: tagId
type: string
required: true
– $ref: “#/parameters/pageParam”
– $ref: “#/parameters/perPageParam”
responses:
“200”:
description: 返回以标签降序排列的帖子列表。
schema:
title: 标签文章列表
type: array
items:
$ref: “#/definitions/Item”
“/users/{userId}”:
get:
parameters:
– in: path
name: userId
type: string
required: true
responses:
“200”:
description: 获取用户信息。
schema:
$ref: “#/definitions/User”
“/users/{userId}/items”:
get:
parameters:
– in: path
name: userId
type: string
required: true
– $ref: “#/parameters/pageParam”
– $ref: “#/parameters/perPageParam”
responses:
“200”:
description: 返回用户的帖子列表。
schema:
title: 用户文章列表
type: array
items:
$ref: “#/definitions/Item”
“/items”:
get:
parameters:
– $ref: “#/parameters/pageParam”
– $ref: “#/parameters/perPageParam”
– name: query
in: query
description: 搜索查询
required: false
type: string
responses:
“200”:
description: 返回帖子列表。
schema:
title: 文章列表
type: array
items:
$ref: “#/definitions/Item”
parameters:
pageParam:
in: query
name: page
description: 页码(1至100)
type: number
perPageParam:
in: query
name: per_page
description: 每页显示的项目数(1至100)
type: number
definitions:
ErrorMessage:
description: 包含错误消息的message属性和表示错误类型的type属性。
type: object
properties:
message:
type: string
type:
type: string
Group:
description: 表示Qiita:Team的小组。
type: object
properties:
created_at:
type: string
id:
type: integer
name:
type: string
private:
type: boolean
updated_at:
type: string
url_name:
type: string
Tag:
description: 标签
properties:
name:
type: string
example: Ruby
versions:
type: array
items:
type: string
example: 0.0.1
User:
properties:
description:
description: 自我介绍
type: string
facebook_id:
type: string
followees_count:
description: 关注该用户的用户数
type: integer
followers_count:
description: 该用户的关注者数
type: integer
github_login_name:
type: string
id:
type: string
items_count:
description: “该用户在qiita.com上发布的公开帖子数量(不包括Qiita:Team上的帖子)”
type: integer
linkedin_id:
type: string
location:
type: string
name:
type: string
organization:
type: string
permanent_id:
description: 用户的整数ID
type: integer
profile_image_url:
description: 用户设置的个人资料图片URL
type: string
twitter_screen_name:
type: string
website_url:
type: string
Item:
type: object
properties:
rendered_body:
type: string
body:
type: string
coediting:
type: boolean
comments_count:
type: integer
created_at:
type: string
id:
type: string
likes_count:
type: string
private:
type: boolean
reactions_count:
type: integer
title:
type: string
updated_at:
type: string
url:
type: string
page_views_count:
type: integer
tags:
type: array
items:
$ref: “#/definitions/Tag”
user:
$ref: “#/definitions/User”
group:
$ref: “#/definitions/Group”

启动 GraphQL Mesh 服务器

建议将GraphQL Mesh服务器启动。以下命令可考虑设置为npm脚本。

$ yarn graphql-mesh serve
yarn run v1.22.4
info: ?️ => Serving GraphQL Mesh GraphiQL: http://localhost:4000/

请在浏览器中打开 http://localhost:4000/ 来启动 GrapiQL 并进行确认。

执行 GraphQL 查询

GraphQL的真骨骼在于通过嵌套描述多个REST API可以获取的信息,从而同时获取Qiita文章的信息和与文章相关的用户信息,这一切都可以在一次查询中完成。

query getItems {
  getItems{
    title
    likesCount
    user {
      name
      itemsCount
      organization
      description
    }
  }
}

看起来已经正确地获取到了。

image

此外,能准确解读 OpenAPI 模型的定义,并且能将其正确地映射到 GraphQL 的模式定义中,这真是太棒了。

image

GraphQL Mesh 的使用方式

GraphQL Mesh充当后端API的代理。由于这个特性,它可以作为客户端的网关,并且可以组合多个后端进行配置。

另外,当多个微服务进行内部相互通信时,也可以选择采用HUB结构。

这个项目似乎还处于开发的初期阶段,根据GitHub的README文件中记载如下。

注意:该项目还处于早期阶段,未来可能会有重大变化。

未来可能会有重大变更。然而,我对这个工具的核心概念非常受到感动。如果像AWS的AppSync这样的GraphQL托管服务也采用这种思想,将对Web API行业产生重大影响。

广告
将在 10 秒后关闭
bannerAds