Skip to content

Commit

Permalink
feat: @requires directive on different services as gateway (#470)
Browse files Browse the repository at this point in the history
  • Loading branch information
Simone Sanfratello authored Apr 28, 2021
1 parent 7a0f72e commit bc83aad
Show file tree
Hide file tree
Showing 14 changed files with 799 additions and 86 deletions.
18 changes: 17 additions & 1 deletion bench.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
#! /bin/bash

./node_modules/.bin/autocannon -c 100 -d 5 -p 10 --on-port '/graphql?query={add(x:2,y:2)}' -- node examples/basic.js
# from https://github.com/mercurius-js/auth/tree/main/bench

echo '=============================='
echo '= Normal Mode ='
echo '=============================='
npx concurrently --raw -k \
"node ./bench/standalone.js" \
"npx wait-on tcp:3000 && node ./bench/standalone-bench.js"

echo '==============================='
echo '= Gateway Mode ='
echo '==============================='
npx concurrently --raw -k \
"node ./bench/gateway-service-1.js" \
"node ./bench/gateway-service-2.js" \
"npx wait-on tcp:3001 tcp:3002 && node ./bench/gateway.js" \
"npx wait-on tcp:3000 && node ./bench/gateway-bench.js"
44 changes: 44 additions & 0 deletions bench/gateway-bench.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict'

const autocannon = require('autocannon')

const query = `query {
me {
id
name
nickname: name
topPosts(count: 2) {
pid
author {
id
}
}
}
topPosts(count: 2) {
pid
}
}`

const instance = autocannon(
{
url: 'http://localhost:3000/graphql',
connections: 100,
title: '',
method: 'POST',
headers: {
'content-type': 'application/json', 'x-user': 'admin'
},
body: JSON.stringify({ query })
},
(err) => {
if (err) {
console.error(err)
}
}
)

process.once('SIGINT', () => {
instance.stop()
})

autocannon.track(instance, { renderProgressBar: true })
61 changes: 61 additions & 0 deletions bench/gateway-service-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict'

const Fastify = require('fastify')
const mercurius = require('..')

const app = Fastify()

const users = {
u1: {
id: 'u1',
name: 'John'
},
u2: {
id: 'u2',
name: 'Jane'
}
}

const schema = `
directive @auth(
requires: Role = ADMIN,
) on OBJECT | FIELD_DEFINITION
enum Role {
ADMIN
REVIEWER
USER
UNKNOWN
}
type Query @extends {
me: User
}
type User @key(fields: "id") {
id: ID!
name: String! @auth(requires: ADMIN)
}`

const resolvers = {
Query: {
me: (root, args, context, info) => {
return users.u1
}
},
User: {
__resolveReference: (user, args, context, info) => {
return users[user.id]
}
}
}

app.register(mercurius, {
schema,
resolvers,
federationMetadata: true,
graphiql: false,
jit: 1
})

app.listen(3001)
91 changes: 91 additions & 0 deletions bench/gateway-service-2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
'use strict'

const Fastify = require('fastify')
const mercurius = require('..')

const app = Fastify()

const posts = {
p1: {
pid: 'p1',
title: 'Post 1',
content: 'Content 1',
authorId: 'u1'
},
p2: {
pid: 'p2',
title: 'Post 2',
content: 'Content 2',
authorId: 'u2'
},
p3: {
pid: 'p3',
title: 'Post 3',
content: 'Content 3',
authorId: 'u1'
},
p4: {
pid: 'p4',
title: 'Post 4',
content: 'Content 4',
authorId: 'u1'
}
}

const schema = `
directive @auth(
requires: Role = ADMIN,
) on OBJECT | FIELD_DEFINITION
enum Role {
ADMIN
REVIEWER
USER
UNKNOWN
}
type Post @key(fields: "pid") {
pid: ID!
author: User @auth(requires: ADMIN)
}
extend type Query {
topPosts(count: Int): [Post] @auth(requires: ADMIN)
}
type User @key(fields: "id") @extends {
id: ID! @external
topPosts(count: Int!): [Post]
}`

const resolvers = {
Post: {
__resolveReference: (post, args, context, info) => {
return posts[post.pid]
},
author: (post, args, context, info) => {
return {
__typename: 'User',
id: post.authorId
}
}
},
User: {
topPosts: (user, { count }, context, info) => {
return Object.values(posts).filter(p => p.authorId === user.id).slice(0, count)
}
},
Query: {
topPosts: (root, { count = 2 }) => Object.values(posts).slice(0, count)
}
}

app.register(mercurius, {
schema,
resolvers,
federationMetadata: true,
graphiql: false,
jit: 1
})

app.listen(3002)
22 changes: 22 additions & 0 deletions bench/gateway.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict'

const Fastify = require('fastify')
const mercurius = require('..')

const app = Fastify()

app.register(mercurius, {
gateway: {
services: [{
name: 'user',
url: 'http://localhost:3001/graphql'
}, {
name: 'post',
url: 'http://localhost:3002/graphql'
}]
},
graphiql: false,
jit: 1
})

app.listen(3000)
43 changes: 43 additions & 0 deletions bench/standalone-bench.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict'

const autocannon = require('autocannon')

const query = `query {
four: add(x: 2, y: 2)
six: add(x: 3, y: 3)
subtract(x: 3, y: 3)
messages {
title
public
private
}
adminMessages {
title
public
private
}
}`

const instance = autocannon(
{
url: 'http://localhost:3000/graphql',
connections: 100,
title: '',
method: 'POST',
headers: {
'content-type': 'application/json', 'x-user': 'admin'
},
body: JSON.stringify({ query })
},
(err) => {
if (err) {
console.error(err)
}
}
)

process.once('SIGINT', () => {
instance.stop()
})

autocannon.track(instance, { renderProgressBar: true })
73 changes: 73 additions & 0 deletions bench/standalone-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
'use strict'

const schema = `
directive @auth(
requires: Role = ADMIN,
) on OBJECT | FIELD_DEFINITION
enum Role {
ADMIN
REVIEWER
USER
UNKNOWN
}
type Message {
title: String!
public: String!
private: String! @auth(requires: ADMIN)
}
type Query {
add(x: Int, y: Int): Int @auth(requires: ADMIN)
subtract(x: Int, y: Int): Int
messages: [Message!]!
adminMessages: [Message!]! @auth(requires: ADMIN)
}
`

const resolvers = {
Query: {
add: async (_, obj) => {
const { x, y } = obj
return x + y
},
subtract: async (_, obj) => {
const { x, y } = obj
return x - y
},
messages: async () => {
return [
{
title: 'one',
public: 'public one',
private: 'private one'
},
{
title: 'two',
public: 'public two',
private: 'private two'
}
]
},
adminMessages: async () => {
return [
{
title: 'admin one',
public: 'admin public one',
private: 'admin private one'
},
{
title: 'admin two',
public: 'admin public two',
private: 'admin private two'
}
]
}
}
}

module.exports = {
schema,
resolvers
}
16 changes: 16 additions & 0 deletions bench/standalone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict'

const Fastify = require('fastify')
const mercurius = require('..')
const { schema, resolvers } = require('./standalone-setup')

const app = Fastify()

app.register(mercurius, {
schema,
resolvers,
graphiql: false,
jit: 1
})

app.listen(3000)
Loading

0 comments on commit bc83aad

Please sign in to comment.