Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit 825b87d

Browse files
authored
feat: Add graphql-jit (#305)
* feat: Add graphql-jit * chore: add graphql_jit in run_benchmarks * chore: bump changes * chore: cache
1 parent 64288a5 commit 825b87d

File tree

7 files changed

+148
-2
lines changed

7 files changed

+148
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Explore and compare the performance of the fastest GraphQL frameworks through ou
2424
[Caliban]: https://github.com/ghostdogpr/caliban
2525
[async-graphql]: https://github.com/async-graphql/async-graphql
2626
[Hasura]: https://github.com/hasura/graphql-engine
27+
[GraphQL JIT]: https://github.com/zalando-incubator/graphql-jit
2728

2829
## Introduction
2930

analyze.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ formattedServerNames=(
1919
["caliban"]="Caliban"
2020
["async_graphql"]="async-graphql"
2121
["hasura"]="Hasura"
22+
["graphql_jit"]="GraphQL JIT"
2223
)
2324

24-
servers=("apollo" "caliban" "netflixdgs" "gqlgen" "tailcall" "async_graphql" "hasura")
25+
servers=("apollo" "caliban" "netflixdgs" "gqlgen" "tailcall" "async_graphql" "hasura" "graphql_jit")
2526
resultFiles=("$@")
2627
declare -A avgReqSecs
2728
declare -A avgLatencies

graphql/graphql_jit/package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "graphql_jit",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"scripts": {
6+
"test": "echo \"Error: no test specified\" && exit 1"
7+
},
8+
"author": "",
9+
"license": "ISC",
10+
"description": "",
11+
"dependencies": {
12+
"@graphql-tools/schema": "^10.0.4",
13+
"axios": "^1.7.2",
14+
"dataloader": "^2.2.2",
15+
"express": "^4.19.2",
16+
"graphql": "^15.9.0",
17+
"graphql-jit": "^0.8.6"
18+
}
19+
}

graphql/graphql_jit/run.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
pwd
3+
cd graphql/graphql_jit
4+
node server.js

graphql/graphql_jit/server.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
const express = require('express');
2+
const { parse } = require('graphql');
3+
const { compileQuery, isCompiledQuery } = require('graphql-jit');
4+
const bodyParser = require('body-parser');
5+
const axios = require('axios');
6+
const DataLoader = require('dataloader');
7+
const { Agent } = require('http');
8+
const { makeExecutableSchema } = require('@graphql-tools/schema');
9+
10+
const httpAgent = new Agent({ keepAlive: true });
11+
const axiosInstance = axios.create({
12+
httpAgent,
13+
proxy: {
14+
protocol: 'http',
15+
host: '127.0.0.1',
16+
port: 3000,
17+
}
18+
});
19+
20+
const typeDefs = `
21+
type Post {
22+
userId: Int
23+
id: Int
24+
title: String
25+
body: String
26+
user: User
27+
}
28+
29+
type User {
30+
id: Int
31+
name: String
32+
username: String
33+
email: String
34+
phone: String
35+
website: String
36+
}
37+
38+
type Query {
39+
greet: String
40+
posts: [Post]
41+
}
42+
`;
43+
44+
const resolvers = {
45+
Query: {
46+
greet: () => 'Hello World!',
47+
posts: async () => {
48+
try {
49+
const response = await axiosInstance.get('http://jsonplaceholder.typicode.com/posts');
50+
return response.data;
51+
} catch (error) {
52+
throw new Error('Failed to fetch posts');
53+
}
54+
},
55+
},
56+
};
57+
58+
const schema = makeExecutableSchema({ typeDefs, resolvers });
59+
60+
async function batchUsers(userIds) {
61+
const requests = userIds.map(async (id) => {
62+
const response = await axiosInstance.get(`http://jsonplaceholder.typicode.com/users/${id}`);
63+
return response.data;
64+
});
65+
return await Promise.all(requests);
66+
}
67+
68+
const app = express();
69+
70+
app.use(bodyParser.json());
71+
72+
// In-memory store for compiled queries
73+
const queryCache = new Map();
74+
75+
app.use('/graphql', async (req, res) => {
76+
const query = req.body.query || req.query.query;
77+
if (!query) {
78+
res.status(400).send('Query not provided');
79+
return;
80+
}
81+
82+
try {
83+
let compiledQuery;
84+
if (queryCache.has(query)) {
85+
compiledQuery = queryCache.get(query);
86+
} else {
87+
const document = parse(query);
88+
compiledQuery = compileQuery(schema, document);
89+
if (!isCompiledQuery(compiledQuery)) {
90+
throw new Error('Error compiling query');
91+
}
92+
queryCache.set(query, compiledQuery);
93+
}
94+
95+
const userLoader = new DataLoader(batchUsers, {
96+
batchScheduleFn: callback => setTimeout(callback, 1),
97+
});
98+
99+
const contextValue = { userLoader };
100+
101+
const result = await compiledQuery.query(
102+
undefined,
103+
contextValue,
104+
req.body.variables,
105+
req.body.operationName
106+
);
107+
108+
res.json(result);
109+
} catch (error) {
110+
res.status(500).send(error.message);
111+
}
112+
});
113+
114+
app.listen(8000, () => {
115+
console.log('Running a GraphQL API server at http://localhost:8000/graphql');
116+
});

run_benchmarks.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ function runBenchmark() {
7272

7373
rm "results.md"
7474

75-
for service in "apollo_server" "caliban" "netflix_dgs" "gqlgen" "tailcall" "async_graphql" "hasura"; do
75+
for service in "apollo_server" "caliban" "netflix_dgs" "gqlgen" "tailcall" "async_graphql" "hasura" "graphql_jit"; do
7676
runBenchmark "graphql/${service}/run.sh"
7777
if [ "$service" == "apollo_server" ]; then
7878
cd graphql/apollo_server/

setup.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,8 @@ cd ../../
3131
cd graphql/hasura
3232
npm install
3333
cd ../../
34+
35+
# For graphql_jit
36+
cd graphql/graphql_jit
37+
npm install
38+
cd ../../

0 commit comments

Comments
 (0)