Skip to content

Commit

Permalink
Lazy Schema Plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan committed Jul 29, 2022
1 parent 5629a5c commit 03e6179
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/healthy-waves-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-yoga/plugin-lazy-schema': major
---

New Lazy Schema
47 changes: 47 additions & 0 deletions packages/plugins/lazy-schema/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@graphql-yoga/plugin-lazy-schema",
"version": "0.0.0",
"description": "Lazy Schema plugin for GraphQL Yoga.",
"repository": {
"type": "git",
"url": "https://github.com/dotansimha/graphql-yoga.git",
"directory": "packages/plugins/apq"
},
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"scripts": {
"check": "tsc --pretty --noEmit"
},
"author": "Arda TANRIKULU <ardatanrikulu@gmail.com>",
"license": "MIT",
"exports": {
".": {
"require": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/cjs/index.js"
},
"import": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
},
"default": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
}
},
"./package.json": "./package.json"
},
"typings": "dist/typings/index.d.ts",
"typescript": {
"definition": "dist/typings/index.d.ts"
},
"publishConfig": {
"directory": "dist",
"access": "public"
},
"peerDependencies": {
"graphql-yoga": "^2.13.4",
"graphql": "*"
},
"type": "module"
}
33 changes: 33 additions & 0 deletions packages/plugins/lazy-schema/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GraphQLError, GraphQLSchema } from 'graphql'
import { Plugin, PromiseOrValue, YogaInitialContext } from 'graphql-yoga'

export const useLazySchema = (
schemaFactory: (request: Request) => PromiseOrValue<GraphQLSchema>,
): Plugin<YogaInitialContext> => {
const schemaByRequest = new WeakMap<Request, GraphQLSchema>()
return {
async onRequest({ request }) {
const schema = await schemaFactory(request)
schemaByRequest.set(request, schema)
},
onEnveloped({ setSchema, context }) {
if (context?.request) {
const schema = schemaByRequest.get(context.request)
if (schema) {
setSchema(schema)
}
} else {
throw new GraphQLError(
'Request object is not available in the context. Make sure you use this plugin with GraphQL Yoga.',
{
extensions: {
http: {
status: 500,
},
},
},
)
}
},
}
}
53 changes: 53 additions & 0 deletions packages/plugins/lazy-schema/test/lazy-schema-plugin.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { makeExecutableSchema } from '@graphql-tools/schema'
import { parse } from 'graphql'
import { createYoga, YogaInitialContext } from 'graphql-yoga'
import { useLazySchema } from '../src'

describe('useLazySchema', () => {
it('should work', async () => {
let count = 0
const schemaFactory = async (request: Request) => {
const countFromContext = request.headers.get('count')
return makeExecutableSchema<YogaInitialContext>({
typeDefs: /* GraphQL */ `
type Query {
foo${countFromContext}: Boolean
}
`,
resolvers: {
Query: {
[`foo${countFromContext}`]: (_, __, { request }) =>
countFromContext === request.headers.get('count'),
},
},
})
}
const yoga = createYoga({
plugins: [useLazySchema(schemaFactory)],
})
while (true) {
if (count === 3) {
break
}
count++
const query = /* GraphQL */ `
query {
foo${count}
}
`
const result = await yoga.fetch('http://localhost:3000/graphql', {
method: 'POST',
body: JSON.stringify({ query }),
headers: {
count: count.toString(),
'Content-Type': 'application/json',
},
})
const { data } = await result.json()
expect(data).toEqual({
[`foo${count}`]: true,
})
}
expect.assertions(3)
})
})

0 comments on commit 03e6179

Please sign in to comment.