前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[翻译]构建带 Subscriptions 的 graphql golang 后端

[翻译]构建带 Subscriptions 的 graphql golang 后端

作者头像
Fred Liang
发布于 2018-08-02 02:06:12
发布于 2018-08-02 02:06:12
2.8K10
代码可运行
举报
文章被收录于专栏:Fred LiangFred Liang
运行总次数:0
代码可运行

GraphQL提供了一种灵活而有效的方式来查询服务器中的数据。 它正在成为设计后端的流行技术,通常会替换或封装一些不灵活的REST API,并让客户负责决定他们需要的数据。 现在有许多用于编写JavaScript的GraphQL客户端和服务器的库和框架,其中最着名的是Apollo和Graphcool 。 Apollo团队还开发了针对WebSockets的GraphQL协议,该协议主要用于Apollo Client和Graphcool中的Subscriptions。

1.介绍graphqlws

今天,我们开放了一个新的Go库来填补这个空白: graphqlw。 它有一个简单的目的:

  1. 实现GraphQL在WebSocket(由所有流行的GraphQL客户端使用),所以不必考虑与net/http无缝集成
  2. 与net/http无缝集成
  3. 提供访问已建立订阅的简单方法,执行身份验证并向相应的客户端发送更新。 你可以在https://github.com/functionalfoundry/graphqlws上的GitHub上找到它。

第1步 - 基本设置

使用graphqlws在WebSocket端点上设置GraphQL很简单。 创建一个GraphQL模式,创建一个订阅管理器,为WebSocket上的通信创建一个HTTP处理程序,然后使用net/http服务处理程序。 或者,您可以定义一个函数来对用户进行身份验证(在建立新连接时,Apollo客户端会将初始WebSocket消息与可选的authToken一起发送;该函数允许将令牌字符串解析为用户)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
	"net/http"

	"github.com/functionalfoundry/graphqlws"
	"github.com/graphql-go/graphql"
)

func main() {
	// Create a GraphQL schema with a subscription object
	schema, err := graphql.NewSchema(graphql.SchemaConfig{
		Subscription: graphql.NewObject(...),
	})
	
	// Create a subscription manager
	subscriptionManager := graphqlws.NewSubscriptionManager(&schema)

	// Create a WebSocket/HTTP handler
	graphqlwsHandler := graphqlws.NewHandler(graphqlws.HandlerConfig{
		// Wire up the GraphqL WebSocket handler with the subscription manager
		SubscriptionManager: subscriptionManager,

		// Optional: Add a hook to resolve auth tokens into users that are
		// then stored on the GraphQL WS connections
		Authenticate: func(authToken string) (interface{}, error) {
			// This is just a dumb example
			return "Joe", nil
		},
	})

	// The handler integrates seamlessly with existing HTTP servers
	http.Handle("/subscriptions", graphqlwsHandler)
	http.ListenAndServe(":8080", nil)
}

第2步 - 使用 Subscriptions

Graphqlws库本身仅仅实现了基于WebSocket协议的GraphQL。 它没有实现任何开箱即用的订阅。 一个典型的服务器实现将监听数据库的变化,并通过识别哪些订阅需要更新,重新执行这些订阅的查询并将结果发送给相应的订阅客户端来对这些更改做出反应。

以下代码示例显示了订阅管理器在任何时候如何检索订阅。 他们按照他们的关系分组。 每个连接都有唯一的ID,可选地,还有前面描述的Authenticate函数返回的用户。

每个订阅都存储订阅查询( QueryVariablesOperationName )以及可用于识别订阅的数据类型(例如FieldsDocument )的其他信息。

使用QueryVariablesOperationName可以在需要时重新执行订阅查询。 然后可以通过SendData方法将结果发送到订阅客户端,如下面的代码示例所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// This assumes you have access to the above subscription manager
subscription := subscriptionManager.Subscriptions()

for _, conn := range subscriptions {
	// Things you have access to here:
	conn.ID()   // The connection ID
	conn.User() // The user returned from the subscription manager's Authenticate
	
	for _, subscription := range subscriptions[conn] {
		// Things you have access to here:
		subscription.ID            // The subscription ID (unique per conn)
		subscription.OperationName // The name of the subcription
		subscription.Query         // The subscription query/queries string
		subscription.Variables     // The subscription variables
		subscription.Document      // The GraphQL AST for the subscription
		subscription.Fields        // The names of top-level queries
		subscription.Connection    // The GraphQL WS connection

		// Prepare an execution context for running the query
		ctx := context.Context()

		// Re-execute the subscription query
		params := graphql.Params{
			Schema:         schema, // The GraphQL schema
			RequestString:  subscription.Query,
			VariableValues: subscription.Variables,
			OperationName:  subscription.OperationName,
			Context:        ctx,
		}
		result := graphql.Do(params)

		// Send query results back to the subscriber at any point
		data := graphqlws.DataMessagePayload{
			// Data can be anything (interface{})
			Data:   result.Data, 
			// Errors is optional ([]error)
			Errors: graphqlws.ErrorsFromGraphQLErrors(result.Errors),
		}
		subscription.SendData(&data)
	}
}

第3步 - 与graphql-go / handler结合使用

结合使用WebSocket端点上的GraphQL和普通的GraphQL HTTP端点,就像其他任何net/http处理程序一样工作。 您只需创建两个处理程序并通过不同的路线提供服务。 以下代码示例演示了这一点。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
	"net/http"
	
	"github.com/functionalfoundry/graphqlws"
	"github.com/graphql-go/graphql"
	"github.com/graphql-go/handler"
)

func main() {
	// Create a GraphQL schema with a subscription object
	schema, err := graphql.NewSchema(graphql.SchemaConfig{
		Subscription: graphql.NewObject(...),
	})
	
	// Create a GraphQL over WebSocket handler
	subscriptionManager := graphqlws.NewSubscriptionManager(&schema)
	graphqlwsHandler := graphqlws.NewHandler(graphqlws.HandlerConfig{
		SubscriptionManager: subscriptionManager,
	})
	
	// Create a GraphQL over HTTP handler
	graphqlHandler := handler.New(&handler.Config{
		Schema: &schema,
		Pretty: true,
		GraphiQL: true,
	})
	
	// Serve both handlers on different endpoints
	http.Handle("/", graphqlHandler)
	http.Handle("/subscriptions", graphqlwsHandler)
	http.ListenAndServe(":8080", nil)
}

概要

如果你已经做到了这一点,你可能有兴趣使用Go作为你自己的GraphQL服务器。 借助graphqlws,现在可以轻松实现服务器端GraphQL订阅。 来吧,你可以尝试一下! 我们希望你喜欢它。


GitHub上提交 bug 或 issue 。

如果您正在寻找下一个项目的React或GraphQL开发方面的帮助,我们很乐意在Functional Foundry处听到您的消息。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
elastic和graphQL可以混用吗
elastic和graphQL可以混用吗
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
Node——activeError: error:0308010C:digital envelope routines::unsupported
启动项目报错error:0308010C:digital envelope routines::unsupported,其实很简单因为node版本的原因,本地默认的版本是v20.15.0,项目是老项目默认的版本是v16.16.0;
思索
2024/08/26
2810
activeError: error:0308010C:digital envelope routines::unsupported
苛求君子,宽纵小人,自以为明察秋毫,而实则反助小人张目——鲁迅 昨天遇到这个报错了: PS D:\project\promotion\vue\gridsome-starter-default-master> gridsome develop Gridsome v0.7.23 Initializing plugins... Load sources - 0s Create GraphQL schema - 0.03s Create pages and templates - 0.15s Genera
阿超
2022/11/16
9390
NodeJs——error:03000086:digital envelope routines::initialization error
vue2前端项目在服务器上打包报错,发现是高版本的node使用的是OpenSSL 3.0,导致的不兼容,所以先临时抛出下环境变量,继续使用老板本的OpenSSL的实现;
思索
2024/08/15
2320
babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babe
webpack报错 错误信息如下: babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'. at Function.Module._resolveFilename (internal/modules/cjs/loader.js:625:15) at Fun
小贝壳
2020/03/05
1.1K0
Syntax Error: Error: Cannot find module ‘node-sass‘
启动vue项目的时候,会出现这样的报错 Syntax Error: Error: Cannot find module ‘node-sass’
王小婷
2025/05/19
900
Syntax Error: Error: Cannot find module ‘node-sass‘
uni-app 安装 scss 引发的报错
最近接手了一个有点历史的小程序,用 uni-app 开发的,没有装 css 预处理器,开发效率有点低,装好之后控制台报错了:
小鑫
2022/04/26
2.7K0
NPM运行保存问题解决
百度了一下,是说版本不对,不是LTS版本,建议我更换Node版本 我本机安装了nvm管理工具,所以通过nvm去查询下node的版本信息
云叶知秋
2024/02/21
4310
多图详解,一次性搞懂Webpack Loader
Webpack 是一个模块化打包工具,它被广泛地应用在前端领域的大多数项目中。利用 Webpack 我们不仅可以打包 JS 文件,还可以打包图片、CSS、字体等其他类型的资源文件。而支持打包非 JS 文件的特性是基于 Loader 机制来实现的。因此要学好 Webpack,我们就需要掌握 Loader 机制。本文阿宝哥将带大家一起深入学习 Webpack 的 Loader 机制,阅读完本文你将了解以下内容:
童欧巴
2021/08/20
1.1K0
多图详解,一次性搞懂Webpack Loader
webpack-dev-server使用报错
参考 https://stackoverflow.com/questions/57724011/how-to-fix-cannot-find-module-webpack-bin-config-yargs
用户6379025
2022/12/26
5150
从零开始学VUE之Webpack(使用CSSLoader和StyleLoader转化样式文件)
拷贝一份项目重新命名为simpleloader(拷贝过程会慢,应为其中存在module依赖)
彼岸舞
2021/06/07
7750
从零开始学VUE之Webpack(使用CSSLoader和StyleLoader转化样式文件)
从零开始学VUE之Webpack(Html打包插件的使用)
看到的错误大概是不能读取属性中的 initialize方法,是一个没有定义的,经过查看源码,发现在最新的版本中确实没有这个方法了,后来看了下老师的版本是3.2.0,我的是5.3.1
彼岸舞
2021/06/07
8850
从零开始学VUE之Webpack(Html打包插件的使用)
nodejs 升级后, vue+webpack 项目 node-sass 报错的解决方法
关于 node 环境升级到 v8^ 以上,node-sass 报错的解决方法 今天给同事电脑升级了一下系统,顺便升级了所有的软件,发现原来好好的项目报错了。报错大致信息如下: ERROR Fail
FungLeo
2018/01/08
2.4K0
vue运行报错:SyntaxError: Cannot use import statement outside a module
PS C:\Users\wangting\Desktop\assets_web_admin\assets_web_admin> npm run dev > vue-element-admin@4.2.1 dev C:\Users\wangting\Desktop\assets_web_admin\assets_web_admin > vue-cli-service serve INFO Starting development server... 10% building 2/2 modules
王小婷
2020/12/31
3.2K0
mac下使用vue create 项目名称 创建项目后无法运行ERROR  Error: Cannot find module 'vue-template-compiler/package.json'
promote:vue_pro wangxinqiang$ npm run serve
botkenni
2019/09/03
6.1K0
mac下使用vue create 项目名称 创建项目后无法运行ERROR  Error: Cannot find module 'vue-template-compiler/package.json'
vite配置vite-plugin-style-import插件后启动报错
不管报什么错,大部分是因为 node版本不够,至少是node 14+的版本才可以,我使用的是node v12.2.0
蓓蕾心晴
2022/05/09
1.7K0
【第9期】webpack入门学习手记(三)
由于微信不允许外部链接,你需要点击页面尾部左下角的阅读原文,才能访问文中的链接。 距离上一次更新这个系列,过去了两天。最近实在是有点忙,没有挤出时间整理。感觉日更还真是困难以下是正文。 管理资源 如果看过之前的系列文章,应该会有一个学习项目webpackStudy,可以从文章下方找到之前的链接。官网给出的示例都是在一个项目中的html页面、package.json和webpack.config.js中进行修改。我为了保留每一小节的代码,并没有按照官网给出的方案处理,而是重新新建的配置文件。可以通过腾讯云开发
siberiawolf
2020/03/24
1.1K0
【第9期】webpack入门学习手记(三)
npm run dev启动报错:Error: Cannot find module 'semver'
PS C:\Users\wangting\Desktop\Wisdom_admin\wisdom_admin> npm run dev > eladmin-web@2.6.0 dev C:\Users\wangting\Desktop\Wisdom_admin\wisdom_admin > vue-cli-service serve internal/modules/cjs/loader.js:985 throw err; ^ Error: Cannot find module 'semver
王小婷
2021/11/24
4K0
npm run dev启动报错:Error: Cannot find module 'semver'
Error: Cannot find module ‘webpack-cli/bin/config-yargs‘的解决方法
Webpack 踩坑笔记: webpack-dev-server 启动命令失败(Error: Cannot find module ‘webpack-cli/bin/config-yargs‘) 果然是版本的问题,引发的血案,之前 "webpack-cli": "^3.3.12", "webpack": "4.16.5", "webpack-bundle-analyzer": "2.13.1", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.1.5", 认真查询后发现,应该降级webpack-cli的版本, 执行:卸载安装,会成功!
张哥编程
2024/12/13
2380
Error: Cannot find module ‘webpack-cli/bin/config-yargs‘的解决方法
找不到node_modules/node-sass/vendor目标的解决办法
但是npm run 命令时出错: no such file or directory, scandir ‘/app/admin/node_modules/node-sass/vendor’
程裕强
2021/05/24
4.7K0
找不到node_modules/node-sass/vendor目标的解决办法
Vue学习笔记之opensslErrorStack: [ ‘error:03000086:digital envelope routines::initialization error‘ ]的问题
将NodeJS版本版本降低到项目制定的版本; 在重新安装之前,一定要卸载干净,具体的卸载方式可以参考这个链接: windows如何把已安装的nodejs高版本降级为低版本(图文教程)
Jetpropelledsnake21
2023/03/07
6.8K0
Vue学习笔记之opensslErrorStack: [ ‘error:03000086:digital envelope routines::initialization error‘ ]的问题
推荐阅读
相关推荐
Node——activeError: error:0308010C:digital envelope routines::unsupported
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验