大部分代码还是来自sofa 的官方文档,同时添加了docker && docker-compose集成
备注: 代码使用typescript 同时运行的时候为了方便直接运行使用ts-node 运行

环境准备

  • docker-compose 文件
version: "3"
services:
api:
build: ./
image: dalongrong/sofa-graphql2rest
ports:
- "4000:4000"
  • dockerfile
FROM node:alpine
WORKDIR /server
COPY . /server
RUN yarn install
CMD ["yarn", "start"]

代码说明

  • package.json 依赖包
{
"name": "sofa-graphql2rest",
"version": "1.0.0",
"license": "MIT",
"main": "server.js",
"scripts": {
"start": "ts-node index.ts"
},
"dependencies": {
"body-parser": "1.18.3",
"chalk": "2.4.2",
"express": "4.16.4",
"express-graphql": "0.7.1",
"graphql": "^14.0.2",
"graphql-subscriptions": "^1.0.0",
"graphql-tag": "2.10.0",
"graphql-tools": "4.0.3",
"sofa-api": "^0.2.2",
"swagger-ui-express": "4.0.2"
},
"devDependencies": {
"@types/swagger-ui-express": "3.0.0",
"@types/body-parser": "1.17.0",
"@types/express": "4.16.0",
"@types/express-graphql": "0.6.2",
"@types/graphql": "14.0.3",
"esm": "^3.0.84",
"ts-loader": "^5.3.3",
"ts-node": "7.0.1",
"typescript": "3.2.2"
}
}
  • graphql api 开发
    基于graphql-tools,同时集成express-graphql 以及swagger open api 文档
    graphql schema 定义 type.ts
import gql from 'graphql-tag';

export const typeDefs = gql`
type Pizza {
dough: String!
toppings: [String!]
} type Salad {
ingredients: [String!]!
} union Food = Pizza | Salad type Book {
id: ID!
title: String!
} type User {
id: ID!
name: String!
favoritePizza: Pizza!
favoriteBook: Book!
favoriteFood: Food!
shelf: [Book!]!
} type Post {
comments(filter: String!): [String!]
} type Query {
me: User
user(id: ID!): User
users: [User!]
usersLimit(limit: Int!): [User!]
usersSort(sort: Boolean!): [User!]
book(id: ID!): Book
books: [Book!]
never: String
feed: [Post]
} type Mutation {
addBook(title: String!): Book
} type Subscription {
onBook: Book
} schema {
query: Query
mutation: Mutation
subscription: Subscription
}
`;

resolvers 定义 resolvers.ts 同时集成了subscription

import { PubSub } from 'graphql-subscriptions';

const pubsub = new PubSub();

import {
UsersCollection,
BooksCollection,
PostsCollection,
} from './collections'; const BOOK_ADDED = 'BOOK_ADDED'; export const resolvers: any = {
Query: {
me() {
return UsersCollection.get(1);
},
user(_: any, { id }: any) {
return UsersCollection.get(id);
},
users() {
return UsersCollection.all();
},
usersLimit(_: any, { limit }: any) {
return UsersCollection.all().slice(0, limit);
},
usersSort(_: any, { sort }: any) {
const users = UsersCollection.all();
return sort ? users.sort((a, b) => b.id - a.id) : users;
},
book(_: any, { id }: any) {
return BooksCollection.get(id);
},
books() {
return BooksCollection.all();
},
feed() {
return PostsCollection.all();
},
},
Mutation: {
addBook(_: any, { title }: any) {
const book = BooksCollection.add(title); pubsub.publish(BOOK_ADDED, { onBook: book }); return book;
},
},
Subscription: {
onBook: {
subscribe: () => pubsub.asyncIterator([BOOK_ADDED]),
},
},
Food: {
__resolveType(obj: any) {
if (obj.ingredients) {
return 'Salad';
} if (obj.toppings) {
return 'Pizza';
} return null;
},
},
Post: {
comments(post: { comments: string[] }, { filter }: { filter: string }) {
return post.comments.filter(
comment =>
!filter || comment.toLowerCase().indexOf(filter.toLowerCase()) > -1
);
},
},
};

代码入口
index.ts

import * as express from 'express';
import { makeExecutableSchema } from 'graphql-tools';
import * as bodyParser from 'body-parser';
import * as useGraphQL from 'express-graphql';
import * as swaggerUi from 'swagger-ui-express';
import chalk from 'chalk';
import { resolve } from 'path';
import { typeDefs } from './types';
import { resolvers } from './resolvers';
import * as swaggerDocument from './swagger.json'; // Sofa import sofa, { OpenAPI } from 'sofa-api';
import { logger } from 'sofa-api/dist/logger'; const app = express(); app.use(bodyParser.json()); const schema = makeExecutableSchema({
typeDefs,
resolvers: resolvers as any,
}); const openApi = OpenAPI({
schema,
info: {
title: 'Example API',
version: '3.0.0',
},
}); app.use(
sofa({
schema,
ignore: ['User.favoriteBook'],
onRoute(info) {
openApi.addRoute(info, {
basePath: '',
});
},
})
); openApi.save(resolve(__dirname, './swagger.json')); app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); app.use('/webhook', (req, res) => {
logger.info('Received a webhook', req.body); res.statusCode = 200;
res.statusMessage = 'OK';
res.send();
}); app.use(
'/graphql',
useGraphQL({
schema,
graphiql: true,
})
); const port = 4000; app.listen(port, () => {
const url = `http://localhost:${4000}`; function printUrl(path: string) {
return chalk.gray(url + path);
} console.log(`
${chalk.bold('GraphQL:')} ${printUrl('/graphql')} ${chalk.bold('Queries:')}
me: ${printUrl('/me')}
users: ${printUrl('/users')}
user: ${printUrl('/user/1')}
books: ${printUrl('/books')}
book: ${printUrl('/book/1')} ${chalk.bold('Mutations:')}
addBook: ${printUrl('/add-book')} ${chalk.italic.gray(
'POST: {title}'
)}
`);
});

运行&&测试

  • 运行
docker-compose build && docker-compose up -d
  • 效果
    openapi docs
http://localhost:4000/docs


graphql ui graphiql 工具

http://localhost:4000/graphql

  • 查询执行
    rest api

    graphql api

说明

sofa 在设计上充分graphql 的ast 语法,同时集成了open api ,同时按照设计的方案,可以集成比较多的graphql 的平台,主要是scema

参考资料

https://github.com/rongfengliang/sofa-graphql2rest-docker-compose
https://sofa-api.com/
https://github.com/Urigo/sofa

 
 
 
 

sofa graphql 2 rest api 试用的更多相关文章

  1. sofa graphql 2 rest api webhook 试用

    sofa 的webhook实际上就是将graphql 的subscription 进行了扩展,当接受到sub 请求的时候 再做一次http 的转发处理,方便rest api 的访问 环境准备 环境还是 ...

  2. sofa graphql 2 rest api框架

    sofa 是一个出发点不一样的工具,提供了从graphql 2 rest 的处理,一般现有的框架都在 关注的是rest 2 graphql (大部分还是基于swagger.open api 标准进行设 ...

  3. 记一次通过c#运用GraphQL调用Github api

    阅读目录 GraphQL是什么 .net下如何运用GraphQL 运用GraphQL调用Github api 结语 一.Graphql是什么 最近在折腾使用Github api做个微信小程序练练手,本 ...

  4. 人人都是 API 设计师:我对 RESTful API、GraphQL、RPC API 的思考

    原文地址:梁桂钊的博客 博客地址:http://blog.720ui.com 欢迎关注公众号:「服务端思维」.一群同频者,一起成长,一起精进,打破认知的局限性. 有一段时间没怎么写文章了,今天提笔写一 ...

  5. minio select api 试用

    对于minio 我们可以使用基于sql 的对象内容查询,特别适合进行特定文件内容的获取,强大方便. 以下是一个简单的试用 环境准备 集成了prometheus docker-compose 文件   ...

  6. 百度地图API试用--(初次尝试)

    2016-03-17: 百度地图API申请key的步骤相对简单,不做过多阐述. 初次使用百度地图API感觉有点神奇,有些功能加进来以后有点问题,注释掉等有空再解决. 代码如下: <%@ page ...

  7. hasura graphql server event trigger 试用

    hasura graphql server 是一个很不错的graphql 引擎,当前版本已经支持event triiger 了 使用此功能我们可以方便的集成webhook功能,实现灵活,稳定,快捷的消 ...

  8. haproxy 2.0 dataplaneapi rest api 试用

    我们可以基于haproxy 提供的dataplaneapi 动态进行haproxy 配置的修改,增强haproxy的可编程能力,以下是一个简单 的测试,基于docker-compose运行 环境准备 ...

  9. haproxy 2.0 dataplaneapi rest api 转为graphql

    haproxy 2.0 dataplaneapi rest api 是比较全的,以下是一个简单的集成graphql,通过swagger-to-graphql 转换为graphql api 方便使用 环 ...

随机推荐

  1. vuesheng生命周期

    对着官网的demo写例子,碰到了生命周期钩子方法,之前只是根据官网的图,了解了大概, 现在忍不住想去深扒一下,因此找了几个博客看了下,受益匪浅,故此笔记: 参考:http://www.cnblogs. ...

  2. SQL-12 获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary

    题目描述 获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salaryCREATE TABLE `dept_emp` (`emp_no` int(11) NOT ...

  3. fortran学习网站

    https://www.sciencesoft.cn/Fortran/Index.htm http://m.fcode.cn/

  4. centos7安装maven,git

    1.maven 下载 2.安装包 解压 3.配置maven环境变量 4.检查是否安装成功 5.检查是否安装 git 6.yum 安装 git 7.配置 git 环境变量 8.检查git是否安装成功 1 ...

  5. SharePoint online Multilingual support - Development(2)

    博客地址:http://blog.csdn.net/FoxDave 上一节讲了如何通过Code的方式设置Site和List级别的国际化,本节介绍一下如何设置Content type和Site co ...

  6. nodejs .http模块, cheerio模块 实现 小爬虫.

    代码: var http = require("http"); var cheerio = require("cheerio"); var url = 'htt ...

  7. python Django rest-framework 创建序列化工程步骤

    11创建项目 2创建应用 3stting添加应用(apps)-添加制定数据库-修改显示汉字(zh-hans)-上海时区(Asia/Shanghai) 4主路由添加子路由 5应用里创建子路由 6创建数据 ...

  8. python Django rest-framework 序列化步骤

    django-rest-framework,是一套基于Django 的 REST 框架,是一个强大灵活的构建 Web API 的工具包.本文介绍一下 django-rest-framework 的简单 ...

  9. angular 学习日志

    1.创建项目 npm install -g @angular/cli ng new my-app cd my-app ng serve --open // 或者 npm start 2.生成新模块 n ...

  10. php操作mysql几个常用操作

    1.链接数据库 mysql_connet('数据库地址','数据库账号','数据库密码'); 2.选择数据库 mysql_select_db("数据库名"); 3.设置编码 mys ...