WebSocket을 통한 GraphQL
This article was published on 2020-09-15 by @ The Guild Blog
WebSocket을 통한 GraphQL
A couple of years ago, while I was still working at Apollo, Lee Byron, Rob Zhu, Dotan simha and I worked on the GraphQL Subscriptions spec and the reference implementation.
During that work, we created and merged the reference implementation into graphql-js and created two supporting libraries: graphql-subscriptions and subscriptions-transport-ws. Here is a talk with deep dive into all the details.
Since leaving Apollo, not a lot of work has been gone into those libraries.
That's why I was so thrilled that Denis decided to pick up that important work and create a new library for the WebSocket Protocol.
We will support his work of maintaining the library and standardizing it with the GraphQL over HTTP working group.
This is a part of a lot of exciting work coming up about GraphQL and real-time, so follow us for new things in this space!
Denis will take it away from here!
소개
웹 개발 여정 중 어느 시점에서 실시간 구성 요소를 추가해야 하는 문제에 직면했을 수 있습니다. 브라우저에서 실시간의 동의어는 WebSocket API입니다. This is how MDN's describes it :
The WebSocket API is an advanced technology that makes it possible to open a two-way interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply.
Google Chrome은 WebSocket 프로토콜을 지원하는 최초의 브라우저로 2009년에 지원을 추가했습니다. 2011년에 공식적으로 표준화되기 2년 전입니다. 전이중 서버-클라이언트 통신에 대한 요구가 높아짐에 따라 다른 브라우저도 그 뒤를 따랐습니다.
현재 모든 주요 브라우저는 WebSocket 프로토콜을 지원합니다(Can I Use table 참조).
웹소켓 ❤️ GraphQL
자, 그렇다면 WebSocket을 사용하여 GraphQL subscription
operation에 대한 지원을 추가하려면 어떻게 해야 합니까? 기본 Google 검색을 수행하면 subscriptions-transport-ws
이라는 단일 솔루션에 직면하게 됩니다. 리포지토리를 살펴보고, 최근 댓글을 확인하고, 문제를 읽고, 공개 PR을 하다 보면 수많은 버그와 보안에 미치는 영향을 알아차릴 수 있을 것입니다. A summary can be found here .
저자들은 훌륭한 일을 해냈지만 불행히도 다른 프로젝트와 요구 사항으로 인해 이 잘 수행되었지만 필요한 아이디어를 유지하고 육성하는 데 필요한 시간이 단축되었습니다. 그러나 그것은 정말로 저에게 그들의 유산을 계승하고 그것을 활성화하도록 영감을 주었습니다! 직접 GraphQL을 사용하여 다양한 WebSocket 문제에 직면한 저는 처음부터 새 라이브러리를 작성하기 시작했습니다.
더 이상 고민하지 않고 겸손하게 소개합니다 graphql-ws
. Queries
, Mutations
및 Subscriptions
3가지 GraphQL 작업을 모두 완벽하게 지원하는 new, security first GraphQL over WebSocket Protocol의 일관성 있고 완전한 기능, 제로 종속성, 플러그 앤 플레이, 지연, 단순, 서버 및 클라이언트 구현 . 이 프로토콜은 재단GraphQL over HTTP work group의 도움으로 표준화되고 GraphQL의 일부가 되는 것을 목표로 합니다.
라이브러리는 TypeScript로 작성되었으며 전체 구현은 형식이 지정되고 주석 처리된 코드가 ~1000줄에 불과합니다. 최신 JavaScript 기본 요소와 잘 확립된 WebSocket의 존재를 활용합니다.
시작하려면 어떻게 해야 하나요?
물어봐주셔서 기쁩니다! 방법은 다음과 같습니다.
설치
$ yarn add graphql-ws
GraphQL 스키마 생성
import { buildSchema } from 'graphql'
// Construct a schema, using GraphQL schema language
const schema = buildSchema(`
type Query {
hello: String
}
type Subscription {
greetings: String
}
`)
// The roots provide resolvers for each GraphQL operation
const roots = {
query: {
hello: () => 'Hello World!'
},
subscription: {
greetings: async function* sayHiIn5Languages() {
for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) {
yield { greetings: hi }
}
}
}
}
서버 시작
첨부ws
import ws from 'ws' // yarn add ws
import { useServer } from 'graphql-ws/lib/use/ws'
const server = new ws.Server({
port: 4000,
path: '/graphql'
})
useServer(
// from the previous step
{ schema, roots },
server
)
console.log('Listening to port 4000')
첨부uWebSockets.js
import uWS from 'uWebSockets.js' // yarn add uWebSockets.js@uNetworking/uWebSockets.js#<tag>
import { makeBehavior } from 'graphql-ws/lib/use/uWebSockets'
uWS
.App()
.ws(
'/graphql',
makeBehavior(
// from the previous step
{ schema, roots }
)
)
.listen(4000, (listenSocket) => {
if (listenSocket) {
console.log('Listening to port 4000')
}
})
첨부fastify-websocket
import Fastify from 'fastify' // yarn add fastify
import fastifyWebsocket from 'fastify-websocket' // yarn add fastify-websocket
import { makeHandler } from 'graphql-ws/lib/use/fastify-websocket'
const fastify = Fastify()
fastify.register(fastifyWebsocket)
fastify.get(
'/graphql',
{ websocket: true },
makeHandler(
// from the previous step
{ schema, roots }
)
)
fastify.listen(4000, (err) => {
if (err) {
fastify.log.error(err)
return process.exit(1)
}
console.log('Listening to port 4000')
})
클라이언트 사용
import { createClient } from 'graphql-ws'
const client = createClient({
url: 'ws://welcomer.com:4000/graphql'
})
// query
;(async () => {
const result = await new Promise((resolve, reject) => {
let result
client.subscribe(
{
query: '{ hello }'
},
{
next: (data) => (result = data),
error: reject,
complete: () => resolve(result)
}
)
})
expect(result).toEqual({ hello: 'Hello World!' })
})()
// subscription
;(async () => {
const onNext = () => {
/* handle incoming values */
}
let unsubscribe = () => {
/* complete the subscription */
}
await new Promise((resolve, reject) => {
unsubscribe = client.subscribe(
{
query: 'subscription { greetings }'
},
{
next: onNext,
error: reject,
complete: resolve
}
)
})
expect(onNext).toBeCalledTimes(5) // we say "Hi" in 5 languages
})()
더 알아보시겠습니까?
바닐라 사용의 경우 일부 Getting Started 또는 Recepies 및 Relay 을 사용하여 Apollo Client 에 대한 리포지토리를 빠르게 확인하십시오. 문제를 열거나, 코드에 기여하거나, 단순히 문서를 개선하는 것은 언제나 환영입니다!
저는 @enisdenjo이고 언제든지 GraphQL Slack workspace에서 이 주제에 대해 저와 채팅할 수 있습니다.
읽어주셔서 감사합니다. 행복한 코딩을 하세요! 👋
Reference
이 문제에 관하여(WebSocket을 통한 GraphQL), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/the-guild/graphql-over-websockets-5eke
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
A couple of years ago, while I was still working at Apollo, Lee Byron, Rob Zhu, Dotan simha and I worked on the GraphQL Subscriptions spec and the reference implementation.
During that work, we created and merged the reference implementation into graphql-js and created two supporting libraries: graphql-subscriptions and subscriptions-transport-ws. Here is a talk with deep dive into all the details.
Since leaving Apollo, not a lot of work has been gone into those libraries.
That's why I was so thrilled that Denis decided to pick up that important work and create a new library for the WebSocket Protocol.
We will support his work of maintaining the library and standardizing it with the GraphQL over HTTP working group.
This is a part of a lot of exciting work coming up about GraphQL and real-time, so follow us for new things in this space!
Denis will take it away from here!
The WebSocket API is an advanced technology that makes it possible to open a two-way interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply.
$ yarn add graphql-ws
import { buildSchema } from 'graphql'
// Construct a schema, using GraphQL schema language
const schema = buildSchema(`
type Query {
hello: String
}
type Subscription {
greetings: String
}
`)
// The roots provide resolvers for each GraphQL operation
const roots = {
query: {
hello: () => 'Hello World!'
},
subscription: {
greetings: async function* sayHiIn5Languages() {
for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) {
yield { greetings: hi }
}
}
}
}
import ws from 'ws' // yarn add ws
import { useServer } from 'graphql-ws/lib/use/ws'
const server = new ws.Server({
port: 4000,
path: '/graphql'
})
useServer(
// from the previous step
{ schema, roots },
server
)
console.log('Listening to port 4000')
import uWS from 'uWebSockets.js' // yarn add uWebSockets.js@uNetworking/uWebSockets.js#<tag>
import { makeBehavior } from 'graphql-ws/lib/use/uWebSockets'
uWS
.App()
.ws(
'/graphql',
makeBehavior(
// from the previous step
{ schema, roots }
)
)
.listen(4000, (listenSocket) => {
if (listenSocket) {
console.log('Listening to port 4000')
}
})
import Fastify from 'fastify' // yarn add fastify
import fastifyWebsocket from 'fastify-websocket' // yarn add fastify-websocket
import { makeHandler } from 'graphql-ws/lib/use/fastify-websocket'
const fastify = Fastify()
fastify.register(fastifyWebsocket)
fastify.get(
'/graphql',
{ websocket: true },
makeHandler(
// from the previous step
{ schema, roots }
)
)
fastify.listen(4000, (err) => {
if (err) {
fastify.log.error(err)
return process.exit(1)
}
console.log('Listening to port 4000')
})
import { createClient } from 'graphql-ws'
const client = createClient({
url: 'ws://welcomer.com:4000/graphql'
})
// query
;(async () => {
const result = await new Promise((resolve, reject) => {
let result
client.subscribe(
{
query: '{ hello }'
},
{
next: (data) => (result = data),
error: reject,
complete: () => resolve(result)
}
)
})
expect(result).toEqual({ hello: 'Hello World!' })
})()
// subscription
;(async () => {
const onNext = () => {
/* handle incoming values */
}
let unsubscribe = () => {
/* complete the subscription */
}
await new Promise((resolve, reject) => {
unsubscribe = client.subscribe(
{
query: 'subscription { greetings }'
},
{
next: onNext,
error: reject,
complete: resolve
}
)
})
expect(onNext).toBeCalledTimes(5) // we say "Hi" in 5 languages
})()
Reference
이 문제에 관하여(WebSocket을 통한 GraphQL), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/the-guild/graphql-over-websockets-5eke텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)