我们已经实现了模式拼接,其中GraphQL服务器从两个远程服务器获取模式并将它们拼接在一起.当我们只使用Query和Mutations时,一切都运行正常,但现在我们有一个用例,我们甚至需要缝合订阅,远程模式已经通过它实现了auth.
我们很难搞清楚如何通过网关将connectionParams中收到的授权令牌从客户端传递到远程服务器.
这就是我们如何反省架构:
API网关代码:
const getLink = async(): Promise<ApolloLink> => {
const http = new HttpLink({uri: process.env.GRAPHQL_ENDPOINT, fetch:fetch})
const link = setContext((request, previousContext) => {
if (previousContext
&& previousContext.graphqlContext
&& previousContext.graphqlContext.request
&& previousContext.graphqlContext.request.headers
&& previousContext.graphqlContext.request.headers.authorization) {
const authorization = previousContext.graphqlContext.request.headers.authorization;
return {
headers: {
authorization
}
}
}
else {
return {};
}
}).concat(http);
const wsLink: any = new WebSocketLink(new SubscriptionClient(process.env.REMOTE_GRAPHQL_WS_ENDPOINT, {
reconnect: true,
// There is no way to update connectionParams dynamically without resetting connection
// connectionParams: () => …
Run Code Online (Sandbox Code Playgroud) apollo graphql apollo-server graphql-subscriptions graphql-tools
您好,我遇到了这个问题,我尝试在 nextjs 中使用 graphql 进行订阅,但是出现了问题,我不知道如何修复它。我遇到 websocket 错误 - “与 'ws:/_next/webpack-hmr' 的 WebSocket 连接失败:WebSocket 在建立连接之前已关闭。”
您可以在此处检查代码 - https://github.com/LoQeN00/messenger-2.0.git
我有两个方面。
一方面,我通过使用 ws(Node.js WebSocket 库)或 Socket.io 等库/包来直接使用 WebSocket 协议。在这里,我可以使用测试工具来订阅和处理以ws
“或wss
喜欢”开头的内容ws://localhost:8080
并接收更新。
另一方面,我通过使用 GraphQL 订阅等组件来使用 GraphQL 订阅ApolloGraphQL
。看来这样我应该使用 GraphQL 中嵌入的东西。用这种方式开发的项目无法通过ws://
或wss://
地址访问,或者至少我不知道。
我的问题是两者之间有什么区别?GraphQL 订阅是建立在 WebSocket 之上的吗?如果是,怎么办?如何通过ws://
或wss://
url 访问 GraphQL 订阅?
我正在尝试升级我们的 NestJS GraphQL 订阅服务器以利用graphql-ws
而不是当前的subscriptions-transport-ws
(如NestJS 文档所建议的)。我将NestJS版本升级到
"@nestjs/core": "^8.0.6",
"@nestjs/graphql": "^9.0.4",
"@nestjs/platform-express": "^8.0.6",
"graphql": "^15.5.3",
"graphql-tools": "^8.2.0",
"apollo-server-express": "^3.3.0",
Run Code Online (Sandbox Code Playgroud)
之后,我将subscriptions
选项添加到App.Module
:
GraphQLModule.forRoot({
autoSchemaFile: true,
sortSchema: true,
playground: true,
installSubscriptionHandlers: true,
subscriptions: {
'graphql-ws': true
},
}),
Run Code Online (Sandbox Code Playgroud)
但是,当我(在操场上)订阅以前有效的订阅时,我得到:
{
"error": "Could not connect to websocket endpoint ws://localhost:8880/graphql. Please check if the endpoint url is correct."
}
Run Code Online (Sandbox Code Playgroud)
在控制台中我得到:
WebSocket protocol error occured. It was most likely caused due to an unsupported subprotocol "graphql-ws" requested by …
Run Code Online (Sandbox Code Playgroud) 我最近开始使用GraphQL,并且能够在AWS Lambda上成功设置它,为我提供了"无服务器"架构.但是,我想利用GraphQL订阅来获得更多实时功能.
我了解AWS Lambda不允许使用WebSockets,因为只要函数运行或达到超时限制,连接就会持续.
但是有没有办法设置GraphQL后端,以便它可以利用订阅并将其保留在AWS服务中,并使其像"无服务器"应用程序一样扩展.
类似于使用AWS Lambda进行GraphQL查询和变异,然后使用不同的AWS服务进行GraphQL订阅.
aws-lambda graphql serverless-framework graphql-subscriptions aws-appsync
我计划使用AWS Appsync在lambda函数中迁移graphQL端点,该函数由POST网关通过API网关触发.我正在研究AppSync主要是因为订阅,我无法使用Lambda函数创建.
我的身份验证机制基于Auth0,使用无密码,我的授权机制基于DynamoDB中几个表的数据,并且嵌入在graphQL解析器中,如Facebook和Apollo所推荐的那样.
更重要的是,它基于请求的每个部分,包括检查调用查询/变异的权限,之后,查询中包含的不同实体,因为正在触发相应的解析器.
据我所知,这远远不能在AWS AppSync中实现,因为它强制使用Cognito.也许某种自定义授权器,如API网关可以完成工作,但它仍然不确定,因为它需要在graphQL请求解析期间执行多次(请记住,除了初始操作检查之外,每个嵌套对象一个).
也许我可以使用通知和刷新查询来解决订阅问题,但我也要研究它.
还有其他人有这个问题吗?你打算怎么做,或者已经解决了?
任何帮助都感激不尽
卡洛斯
lambda amazon-web-services graphql graphql-subscriptions aws-appsync
我正在尝试基于 websocket 制作实时应用程序并有两个选择。一个是socket.io
,另一个是GraphQL Subscriptions
。但很难找到这些之间的比较。
选择其中一种的标准是什么?性能上有什么区别吗?
我有一个 GraphQL 驱动的应用程序。查询和变异部分运行良好。我尝试添加 GraphQL 订阅。
服务器 GraphQL 订阅部分代码的灵感来自apollographql/subscriptions-transport-ws的自述文件中的演示。
另请检查代码中的注释以获取更多详细信息。
import Koa from 'koa';
import Router from 'koa-router';
import graphqlHTTP from 'koa-graphql';
import asyncify from 'callback-to-async-iterator';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import firebase from 'firebase-admin';
import { execute, subscribe } from 'graphql';
import { GraphQLObjectType, GraphQLString } from 'graphql';
const MeType = new GraphQLObjectType({
name: 'Me',
fields: () => ({
name: { type: GraphQLString },
// ...
}),
});
const listenMe = async (callback) => {
// Below …
Run Code Online (Sandbox Code Playgroud) 我需要订阅来返回所请求类型的初始状态。
我的应用程序中有任务系统,一个任务可能有多个状态:CREATED
、QUEUED
、RUNNING
、COMPLETED
、CANCELLED
等CANCELLING
。创建任务时,它具有CREATED
状态,然后根据其类型经历多个状态,直到它成为COMPLETED
。
有一个订阅taskUpdated(id: ID!): Task
,它的作用就是它所说的。这是一个订阅解析器:
taskUpdated: {
subscribe: async (...args) => {
try {
// get initial task state
const initialTaskData = await resolveTask(args[1].input);
const cb = withFilter(
(_, { input }) => {
const iterator = tasksPubsub.asyncIterator(TASK_UPDATED);
// Set initial task state in the iterator?
return iterator;
},
(payload, variables) => {
return payload.id === variables.input.id;
},
);
return cb.apply(null, args); …
Run Code Online (Sandbox Code Playgroud) 我想订阅 GraphQL 服务器。该应用程序在 NodeJS 脚本中运行(即不在网络浏览器中)。
这是我目前所做的:
const fetch = require("node-fetch").default;
const apollo = require("apollo-boost");
const ApolloClient = apollo.default;
const { gql } = require("apollo-server");
const apolloClient = new ApolloClient({
uri: "http://localhost:4000/graphql",
fetch
});
apolloClient.subscribe({
query: gql`
subscription {
startTaskRequested {
pkRobot
taskName
}
}
`,
}).subscribe({
next(x) { console.log(x) },
error(err) { console.log(`Finished with error: ${ err }`) },
complete() { console.log('Finished') }
});
Run Code Online (Sandbox Code Playgroud)
结果输出是:
{ data: { startTaskRequested: null } }
Finished
Run Code Online (Sandbox Code Playgroud)
在 GraphQL Server 上,我可以看到相应的解析器从未被调用。
如果我使用 Apollo 的 …
graphql ×9
apollo ×2
aws-appsync ×2
socket.io ×2
websocket ×2
aws-lambda ×1
graphql-js ×1
javascript ×1
koa ×1
lambda ×1
nestjs ×1
next.js ×1
node.js ×1
prisma ×1
reactjs ×1
ws ×1