├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── benchmark-bench.js ├── benchmark-compare.js ├── benchmark.js ├── benchmarks ├── apollo-as-integrations-fastify+graphql-jit+type-graphql.js ├── apollo-as-integrations-fastify+graphql-jit.js ├── apollo-as-integrations-fastify.js ├── apollo-as-koa-integrations+graphql-jit+type-graphql.js ├── apollo-opentracing.js ├── apollo-schema+async.js ├── apollo-server-express-tracing.js ├── apollo-server-express.js ├── benzene-http.js ├── benzene-jit-http.js ├── bun-yoga-jit.js ├── bun-yoga.js ├── core-graphql-jit-buf-fjs.js ├── core-graphql-jit-buf.js ├── core-graphql-jit-str.js ├── express-REST.js ├── express-gql.js ├── fastify-REST.js ├── fastify-express-graphql-jit.js ├── fastify-express-graphql-typed-jit.js ├── fastify-express-grapql-typed.js ├── go-graphql.js ├── graphql-api-koa+graphql-jit.js ├── graphql-api-koa.js ├── graphql-compose+async.js ├── graphql-http+async-middleware.js ├── graphql-http+async.js ├── graphql-http+graphql-compose.js ├── graphql-http+graphql-jit+graphql-compose.js ├── graphql-http+graphql-jit+type-graphql.js ├── graphql-http+graphql-jit.js ├── graphql-http+middleware.js ├── graphql-http+type-graphql.js ├── graphql-http-dd-trace-less.js ├── graphql-http-dd-trace-no-plugin.js ├── graphql-http-dd-trace.js ├── graphql-http.js ├── mercurius+graphql-compose.js ├── mercurius+graphql-jit+otel-instrumentation.js ├── mercurius+graphql-jit+type-graphql.js ├── mercurius+graphql-jit.js ├── mercurius.js ├── rust-graphql.js ├── uWebSockets-graphql+jit.js └── yoga-graphql.js ├── lib ├── autocannon.js ├── bench.js ├── choices.js ├── data.js ├── instrumentations │ └── otel-instrumentation.js └── schemas │ ├── createApolloSchema.js │ ├── createGraphqlCompose.js │ ├── createTypeGraphQLSchema.js │ └── createTypeGraphQLSchema.ts ├── other-benchmarks ├── bun │ ├── .gitignore │ ├── .prettierrc │ ├── README.md │ ├── bun.lockb │ ├── data.ts │ ├── package.json │ ├── schema.ts │ ├── server-jit.ts │ ├── server.ts │ └── tsconfig.json ├── go-gql │ ├── go.mod │ ├── go.sum │ ├── gqlgen.yml │ ├── graph │ │ ├── generated │ │ │ └── generated.go │ │ ├── model │ │ │ └── models_gen.go │ │ ├── resolver.go │ │ ├── schema.graphqls │ │ └── schema.resolvers.go │ ├── server.go │ └── src │ │ └── data │ │ └── data.go └── rust-gql │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ ├── main.rs │ └── schema.rs ├── package.json ├── run ├── application_config.json ├── application_config_meta.json └── router.json └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | **/node_modules/** 2 | dist/** 3 | lib/schemas/createTypeGraphQLSchema.js -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | commonjs: true, 5 | es2021: true, 6 | }, 7 | extends: ["prettier"], 8 | parser: "@typescript-eslint/parser", 9 | parserOptions: { 10 | ecmaVersion: 12, 11 | }, 12 | plugins: ["@typescript-eslint", "prettier"], 13 | rules: { 14 | "no-console": 0, 15 | "prettier/prettier": "error", 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # 0x 40 | profile-* 41 | 42 | # mac files 43 | .DS_Store 44 | 45 | # vim swap files 46 | *.swp 47 | 48 | # webstorm 49 | .idea 50 | 51 | # flamegraphs 52 | profile* 53 | 54 | # lock files 55 | yarn.lock 56 | package-lock.json 57 | 58 | # benchmark results 59 | results 60 | 61 | dist 62 | results100 63 | results5 64 | 65 | # Rust 66 | other-benchmarks/rust-gql/target -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | results 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | save-exact=false 3 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.json -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "trailingComma": "all", 5 | "bracketSpacing": true, 6 | "semi": true, 7 | "useTabs": false, 8 | "bracketSameLine": true, 9 | "endOfLine": "auto" 10 | } 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "8" 5 | - "10" 6 | - "11" 7 | 8 | notifications: 9 | email: 10 | on_success: never 11 | on_failure: always 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at cagataycali@icloud.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 ./c² 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TL;DR 2 | 3 | - graphql-jit helps 4 | - apollo-server adds overhead 5 | - tracing resolvers kills performance 6 | - type-graphql adds overhead 7 | 8 | # Explanation 9 | 10 | For further details, please check out [this video](https://www.youtube.com/watch?v=JbV7MCeEPb8). 11 | 12 | # Usage 13 | 14 | ``` 15 | git clone https://github.com/benawad/benchmarks 16 | cd benchmarks 17 | npm install 18 | npm start 19 | ``` 20 | 21 | # Benchmarks 22 | duration: 60.14s 23 | connections: 100 24 | pipelining: 5 25 | 26 | | Server | Requests/s | Latency | Throughput/Mb | 27 | | :-- | --: | :-: | --: | 28 | | [rust-graphql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/rust-graphql.js) | 66804.8 | 7.00 | 391.47 | 29 | | [bun-yoga-jit](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/bun-yoga-jit.js) | 13934.5 | 35.38 | 94.31 | 30 | | [go-graphql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/go-graphql.js) | 13567.7 | 36.36 | 79.78 | 31 | | [uWebSockets-graphql+jit](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/uWebSockets-graphql+jit.js) | 12364.5 | 39.93 | 83.33 | 32 | | [core-graphql-jit-str](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/core-graphql-jit-str.js) | 9154.3 | 54.11 | 61.95 | 33 | | [core-graphql-jit-buf](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/core-graphql-jit-buf.js) | 9120.5 | 54.31 | 61.73 | 34 | | [benzene-jit-http](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/benzene-jit-http.js) | 8756.6 | 56.58 | 59.69 | 35 | | [apollo-schema+async](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/apollo-schema+async.js) | 8589.9 | 57.69 | 2.38 | 36 | | [graphql-http+middleware](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http+middleware.js) | 8576.5 | 57.78 | 2.37 | 37 | | [graphql-http](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http.js) | 8567.2 | 57.85 | 2.37 | 38 | | [graphql-http+type-graphql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http+type-graphql.js) | 8566.9 | 57.84 | 2.37 | 39 | | [graphql-http+async-middleware](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http+async-middleware.js) | 8429.6 | 58.80 | 2.33 | 40 | | [graphql-compose+async](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-compose+async.js) | 8415.9 | 58.90 | 2.33 | 41 | | [graphql-http+graphql-jit+type-graphql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http+graphql-jit+type-graphql.js) | 8415.1 | 58.90 | 2.33 | 42 | | [graphql-http+async](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http+async.js) | 8388.3 | 59.09 | 2.32 | 43 | | [graphql-http+graphql-jit+graphql-compose](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http+graphql-jit+graphql-compose.js) | 8350.7 | 59.35 | 2.31 | 44 | | [core-graphql-jit-buf-fjs](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/core-graphql-jit-buf-fjs.js) | 8251.5 | 60.06 | 55.85 | 45 | | [fastify-REST](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/fastify-REST.js) | 8247.3 | 60.11 | 76.00 | 46 | | [graphql-http+graphql-compose](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http+graphql-compose.js) | 8227.7 | 60.25 | 2.28 | 47 | | [graphql-http+graphql-jit](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http+graphql-jit.js) | 8157.3 | 60.77 | 2.26 | 48 | | [bun-yoga](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/bun-yoga.js) | 8132.2 | 60.96 | 55.04 | 49 | | [graphql-http-dd-trace-no-plugin](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http-dd-trace-no-plugin.js) | 7920.7 | 62.60 | 2.19 | 50 | | [mercurius+graphql-jit](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/mercurius+graphql-jit.js) | 7624.2 | 65.06 | 51.95 | 51 | | [mercurius+graphql-jit+type-graphql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/mercurius+graphql-jit+type-graphql.js) | 6446.1 | 77.03 | 43.92 | 52 | | [graphql-http-dd-trace](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http-dd-trace.js) | 5410.9 | 91.85 | 1.50 | 53 | | [graphql-http-dd-trace-less](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-http-dd-trace-less.js) | 5313.5 | 93.52 | 1.47 | 54 | | [express-REST](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/express-REST.js) | 4988.7 | 99.66 | 46.28 | 55 | | [benzene-http](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/benzene-http.js) | 4776.6 | 104.11 | 32.56 | 56 | | [mercurius+graphql-jit+otel-instrumentation](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/mercurius+graphql-jit+otel-instrumentation.js) | 4717.1 | 105.42 | 32.14 | 57 | | [mercurius+graphql-compose](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/mercurius+graphql-compose.js) | 4468.4 | 111.31 | 30.44 | 58 | | [mercurius](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/mercurius.js) | 4400.1 | 113.05 | 29.98 | 59 | | [graphql-api-koa+graphql-jit](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-api-koa+graphql-jit.js) | 4223.8 | 117.78 | 28.75 | 60 | | [yoga-graphql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/yoga-graphql.js) | 3815.7 | 130.43 | 25.99 | 61 | | [graphql-api-koa](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/graphql-api-koa.js) | 3046.7 | 163.43 | 20.73 | 62 | | [apollo-as-integrations-fastify+graphql-jit](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/apollo-as-integrations-fastify+graphql-jit.js) | 2722.3 | 182.94 | 18.61 | 63 | | [apollo-as-integrations-fastify+graphql-jit+type-graphql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/apollo-as-integrations-fastify+graphql-jit+type-graphql.js) | 2652.8 | 187.71 | 18.14 | 64 | | [apollo-as-integrations-fastify](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/apollo-as-integrations-fastify.js) | 2578.5 | 192.82 | 17.63 | 65 | | [apollo-as-koa-integrations+graphql-jit+type-graphql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/apollo-as-koa-integrations+graphql-jit+type-graphql.js) | 2385.0 | 207.45 | 16.41 | 66 | | [apollo-server-express-tracing](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/apollo-server-express-tracing.js) | 2131.1 | 230.22 | 14.77 | 67 | | [apollo-server-express](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/apollo-server-express.js) | 2116.2 | 231.06 | 14.67 | 68 | | [apollo-opentracing](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/apollo-opentracing.js) | 0.0 | 0.00 | 0.00 | 69 | | [express-gql](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/express-gql.js) | 0.0 | 0.00 | 0.00 | 70 | | [fastify-express-graphql-jit](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/fastify-express-graphql-jit.js) | 0.0 | 0.00 | 0.00 | 71 | | [fastify-express-graphql-typed-jit](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/fastify-express-graphql-typed-jit.js) | 0.0 | 0.00 | 0.00 | 72 | | [fastify-express-grapql-typed](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/fastify-express-grapql-typed.js) | 0.0 | 0.00 | 0.00 | 73 | -------------------------------------------------------------------------------- /benchmark-bench.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const bench = require("./lib/bench"); 4 | const { choices } = require("./lib/choices"); 5 | 6 | async function getInquirer() { 7 | const { default: inquirer } = await import("inquirer"); 8 | 9 | return inquirer; 10 | } 11 | 12 | function select(callback) { 13 | getInquirer() 14 | .then((inquirer) => { 15 | return inquirer.prompt([ 16 | { 17 | type: "checkbox", 18 | message: "Select packages", 19 | name: "list", 20 | choices: [...choices.map((name) => ({ name }))], 21 | validate(answer) { 22 | if (answer.length < 1) { 23 | return "You must choose at least one package."; 24 | } 25 | return true; 26 | }, 27 | }, 28 | ]); 29 | }) 30 | .then((answers) => { 31 | callback(answers.list); 32 | }); 33 | } 34 | 35 | getInquirer() 36 | .then((inquirer) => { 37 | return inquirer.prompt([ 38 | { 39 | type: "confirm", 40 | name: "all", 41 | message: "Do you want to run all benchmark tests?", 42 | default: false, 43 | }, 44 | { 45 | type: "input", 46 | name: "connections", 47 | message: "How many connections do you need?", 48 | default: 5, 49 | validate(value) { 50 | return !Number.isNaN(parseFloat(value)) || "Please enter a number"; 51 | }, 52 | filter: Number, 53 | }, 54 | { 55 | type: "input", 56 | name: "pipelining", 57 | message: "How many pipelines do you need?", 58 | default: 1, 59 | validate(value) { 60 | return !Number.isNaN(parseFloat(value)) || "Please enter a number"; 61 | }, 62 | filter: Number, 63 | }, 64 | { 65 | type: "input", 66 | name: "duration", 67 | message: "How long should it take?", 68 | default: 5, 69 | validate(value) { 70 | return !Number.isNaN(parseFloat(value)) || "Please enter a number"; 71 | }, 72 | filter: Number, 73 | }, 74 | ]); 75 | }) 76 | .then((opts) => { 77 | if (!opts.all) { 78 | select((list) => bench(opts, list)); 79 | } else { 80 | bench(opts, choices); 81 | } 82 | }); 83 | -------------------------------------------------------------------------------- /benchmark-compare.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const chalk = require("chalk"); 4 | const Table = require("cli-table"); 5 | const { join } = require("path"); 6 | const { readdirSync, readFileSync } = require("fs"); 7 | const { program } = require("commander"); 8 | const { compare } = require("./lib/autocannon"); 9 | 10 | program 11 | .option("-t, --table", "table") 12 | .option("-p, --percentage", "percentage") 13 | .option("-c --commandlineMdTable", "Print a table for use in MarkDown") 14 | .parse(process.argv); 15 | 16 | const options = program.opts(); 17 | const resultsPath = join(process.cwd(), "results"); 18 | let choices = readdirSync(resultsPath) 19 | .filter((file) => file.match(/(.+)\.json$/)) 20 | .sort() 21 | .map((choice) => choice.replace(".json", "")); 22 | 23 | const bold = (writeBold, str) => (writeBold ? chalk.bold(str) : str); 24 | if (!choices.length) { 25 | console.log(chalk.red("Benchmark to gather some results to compare.")); 26 | } else if (options.table && !options.percentage) { 27 | const tableSeparatorChars = options.commandlineMdTable 28 | ? { 29 | top: "", 30 | "top-left": "", 31 | "top-mid": "", 32 | "top-right": "", 33 | bottom: "", 34 | "bottom-left": "", 35 | "bottom-mid": "", 36 | "bottom-right": "", 37 | mid: "", 38 | "left-mid": "", 39 | "mid-mid": "", 40 | "right-mid": "", 41 | left: "|", 42 | right: "|", 43 | middle: "|", 44 | } 45 | : {}; 46 | const table = new Table({ 47 | chars: tableSeparatorChars, 48 | head: ["Server", "Requests/s", "Latency", "Throughput/Mb"], 49 | }); 50 | if (options.commandlineMdTable) { 51 | table.push([":--", "--:", ":-:", "--:"]); 52 | } 53 | 54 | const dataArray = []; 55 | choices.forEach((file) => { 56 | const content = readFileSync(`${resultsPath}/${file}.json`); 57 | dataArray.push(JSON.parse(content.toString())); 58 | }); 59 | dataArray.sort( 60 | (a, b) => parseFloat(b.requests.mean) - parseFloat(a.requests.mean), 61 | ); 62 | 63 | dataArray.forEach((data, i) => { 64 | if (i === 0) { 65 | console.log( 66 | `duration: ${data.duration}s\nconnections: ${data.connections}\npipelining: ${data.pipelining}`, 67 | ); 68 | console.log(""); 69 | } 70 | const beBold = false; 71 | table.push([ 72 | bold( 73 | beBold, 74 | chalk.blue( 75 | options.commandlineMdTable 76 | ? `[${data.server}](https://github.com/benawad/node-graphql-benchmarks/tree/master/benchmarks/${data.server}.js)` 77 | : data.server, 78 | ), 79 | ), 80 | bold(beBold, data.requests.average.toFixed(1)), 81 | bold(beBold, data.latency.average.toFixed(2)), 82 | bold(beBold, (data.throughput.average / 1024 / 1024).toFixed(2)), 83 | ]); 84 | }); 85 | 86 | console.log(table.toString()); 87 | } else if (options.percentage) { 88 | const data = []; 89 | choices.forEach((file) => { 90 | const content = readFileSync(`${resultsPath}/${file}.json`); 91 | data.push(JSON.parse(content.toString())); 92 | }); 93 | data.sort( 94 | (a, b) => parseFloat(b.requests.mean) - parseFloat(a.requests.mean), 95 | ); 96 | const base = { 97 | name: data[0].server, 98 | request: data[0].requests.mean, 99 | latency: data[0].latency.mean, 100 | throughput: data[0].throughput.mean, 101 | }; 102 | const table = new Table({ 103 | head: [ 104 | "Server", 105 | `Requests/s\n(% of ${base.name})`, 106 | `Latency\n(% of ${base.name})`, 107 | `Throughput/Mb\n(% of ${base.name})`, 108 | ], 109 | }); 110 | data.forEach((result) => { 111 | const beBold = result.server === "fastify"; 112 | const getPct = (base, value) => ((value / base) * 100).toFixed(2); 113 | 114 | table.push([ 115 | bold(beBold, chalk.blue(result.server)), 116 | bold( 117 | beBold, 118 | `${result.requests.mean}\n(${getPct( 119 | base.request, 120 | result.requests.mean, 121 | )})`, 122 | ), 123 | bold( 124 | beBold, 125 | `${result.latency.mean}\n(${getPct( 126 | base.latency, 127 | result.latency.mean, 128 | )})`, 129 | ), 130 | bold( 131 | beBold, 132 | `${(result.throughput.mean / 1024 / 1024).toFixed(2)}\n(${getPct( 133 | base.throughput, 134 | result.throughput.mean, 135 | )})`, 136 | ), 137 | ]); 138 | }); 139 | 140 | console.log(table.toString()); 141 | } else { 142 | async function getInquirer() { 143 | const { default: inquirer } = await import("inquirer"); 144 | 145 | return inquirer; 146 | } 147 | 148 | getInquirer().then((inquirer) => { 149 | return inquirer 150 | .prompt([ 151 | { 152 | type: "list", 153 | name: "choice", 154 | message: "What's your first pick?", 155 | choices, 156 | }, 157 | ]) 158 | .then((firstChoice) => { 159 | choices = choices.filter((choice) => choice !== firstChoice.choice); 160 | inquirer 161 | .prompt([ 162 | { 163 | type: "list", 164 | name: "choice", 165 | message: "What's your second one?", 166 | choices, 167 | }, 168 | ]) 169 | .then((secondChoice) => { 170 | const [a, b] = [firstChoice.choice, secondChoice.choice]; 171 | const result = compare(a, b); 172 | if (result === true) { 173 | console.log(chalk.green.bold(`${a} and ${b} both are fast!`)); 174 | } else { 175 | const fastest = chalk.bold.yellow(result.fastest); 176 | const fastestAverage = chalk.green(result.fastestAverage); 177 | const slowest = chalk.bold.yellow(result.slowest); 178 | const slowestAverage = chalk.green(result.slowestAverage); 179 | const diff = chalk.bold.green(result.diff); 180 | 181 | console.log(` 182 | ${chalk.blue("Both are awesome but")} ${fastest} ${chalk.blue( 183 | "is", 184 | )} ${diff} ${chalk.blue("faster than")} ${slowest} 185 | • ${fastest} ${chalk.blue("request average is")} ${fastestAverage} 186 | • ${slowest} ${chalk.blue("request average is")} ${slowestAverage}`); 187 | } 188 | }); 189 | }); 190 | }); 191 | } 192 | -------------------------------------------------------------------------------- /benchmark.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { program } = require("commander"); 4 | 5 | program 6 | .command("bench", "Benchmark one, multiple or all modules.", { 7 | isDefault: true, 8 | }) 9 | .command("compare", "Compare results by module.") 10 | .parse(process.argv); 11 | -------------------------------------------------------------------------------- /benchmarks/apollo-as-integrations-fastify+graphql-jit+type-graphql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { ApolloServer } = require("@apollo/server"); 4 | const { 5 | default: fastifyApollo, 6 | fastifyApolloDrainPlugin, 7 | } = require("@as-integrations/fastify"); 8 | const { parse } = require("graphql"); 9 | const { compileQuery } = require("graphql-jit"); 10 | const app = require("fastify")(); 11 | const { 12 | createTypeGraphQLSchema, 13 | } = require("../lib/schemas/createTypeGraphQLSchema"); 14 | 15 | const cache = {}; 16 | 17 | createTypeGraphQLSchema().then((schema) => { 18 | const server = new ApolloServer({ 19 | schema, 20 | plugins: [fastifyApolloDrainPlugin(app)], 21 | executor: ({ source, context }) => { 22 | if (!(source in cache)) { 23 | const document = parse(source); 24 | cache[source] = compileQuery(schema, document); 25 | } 26 | 27 | return cache[source].query({}, context, {}); 28 | }, 29 | }); 30 | server.start().then(() => { 31 | app.register(fastifyApollo(server)); 32 | app.listen({ 33 | port: 4001, 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /benchmarks/apollo-as-integrations-fastify+graphql-jit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { ApolloServer } = require("@apollo/server"); 4 | const { 5 | default: fastifyApollo, 6 | fastifyApolloDrainPlugin, 7 | } = require("@as-integrations/fastify"); 8 | const { parse } = require("graphql"); 9 | const { compileQuery } = require("graphql-jit"); 10 | const app = require("fastify")(); 11 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 12 | 13 | const schema = createApolloSchema(); 14 | 15 | const cache = {}; 16 | 17 | const server = new ApolloServer({ 18 | schema, 19 | plugins: [fastifyApolloDrainPlugin(app)], 20 | executor: ({ source, context }) => { 21 | if (!(source in cache)) { 22 | const document = parse(source); 23 | cache[source] = compileQuery(schema, document); 24 | } 25 | 26 | return cache[source].query({}, context, {}); 27 | }, 28 | }); 29 | server.start().then(() => { 30 | app.register(fastifyApollo(server)); 31 | app.listen({ 32 | port: 4001, 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /benchmarks/apollo-as-integrations-fastify.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { ApolloServer } = require("@apollo/server"); 4 | const { 5 | default: fastifyApollo, 6 | fastifyApolloDrainPlugin, 7 | } = require("@as-integrations/fastify"); 8 | const app = require("fastify")(); 9 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 10 | 11 | const schema = createApolloSchema(); 12 | const server = new ApolloServer({ 13 | schema, 14 | plugins: [fastifyApolloDrainPlugin(app)], 15 | }); 16 | 17 | server.start().then(() => { 18 | app.register(fastifyApollo(server)); 19 | app.listen({ 20 | port: 4001, 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /benchmarks/apollo-as-koa-integrations+graphql-jit+type-graphql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { koaMiddleware } = require("@as-integrations/koa"); 4 | const Koa = require("koa"); 5 | const bodyParser = require("koa-bodyparser"); 6 | const cors = require("@koa/cors"); 7 | const { ApolloServer } = require("@apollo/server"); 8 | const { 9 | ApolloServerPluginDrainHttpServer, 10 | } = require("@apollo/server/plugin/drainHttpServer"); 11 | const { parse } = require("graphql"); 12 | const { compileQuery } = require("graphql-jit"); 13 | const { createServer } = require("http"); 14 | const { 15 | createAsyncTypeGraphQLSchema, 16 | } = require("../lib/schemas/createTypeGraphQLSchema"); 17 | 18 | const app = new Koa(); 19 | 20 | const cache = {}; 21 | 22 | const httpServer = createServer(app.callback()); 23 | 24 | createAsyncTypeGraphQLSchema().then((schema) => { 25 | const server = new ApolloServer({ 26 | schema, 27 | executor: ({ source, context }) => { 28 | if (!(source in cache)) { 29 | const document = parse(source); 30 | cache[source] = compileQuery(schema, document); 31 | } 32 | 33 | return cache[source].query({}, context, {}); 34 | }, 35 | plugins: [ApolloServerPluginDrainHttpServer({ httpServer })], 36 | }); 37 | server.start().then(() => { 38 | app.use(cors()); 39 | app.use(bodyParser()); 40 | app.use(koaMiddleware(server, {})); 41 | return new Promise((resolve) => httpServer.listen({ port: 4001 }, resolve)); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /benchmarks/apollo-opentracing.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const cors = require("cors"); 4 | const { ApolloServer } = require("@apollo/server"); 5 | const { expressMiddleware } = require("@apollo/server/express4"); 6 | const OpentracingPlugin = require("apollo-opentracing").default; 7 | const express = require("express"); 8 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 9 | 10 | if (true) { 11 | throw new Error( 12 | "https://github.com/DanielMSchmidt/apollo-opentracing/issues/573", 13 | ); 14 | } 15 | 16 | const app = express(); 17 | const schema = createApolloSchema(); 18 | const server = new ApolloServer({ 19 | schema, 20 | plugins: [ 21 | OpentracingPlugin({ 22 | server: { 23 | startSpan: () => ({ finish: () => ({}) }), 24 | extract: () => ({}), 25 | finish: () => ({}), 26 | }, 27 | local: { 28 | startSpan: () => ({ finish: () => ({}) }), 29 | }, 30 | }), 31 | ], 32 | }); 33 | server.start().then(() => { 34 | app.use("/graphql", cors(), express.json(), expressMiddleware(server, {})); 35 | app.listen(4001); 36 | }); 37 | -------------------------------------------------------------------------------- /benchmarks/apollo-schema+async.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const processRequest = require("graphql-upload/processRequest.js"); 5 | const express = require("express"); 6 | const { 7 | createAsyncApolloSchema, 8 | } = require("../lib/schemas/createApolloSchema"); 9 | 10 | const app = express(); 11 | const schema = createAsyncApolloSchema(); 12 | app.use( 13 | "/graphql", 14 | createHandler({ 15 | schema, 16 | async parseRequestParams(req) { 17 | const params = await processRequest(req.raw, req.context.res); 18 | if (Array.isArray(params)) { 19 | throw new Error("Batching is not supported"); 20 | } 21 | return { 22 | ...params, 23 | // variables must be an object as per the GraphQL over HTTP spec 24 | variables: Object(params.variables), 25 | }; 26 | }, 27 | }), 28 | ); 29 | app.listen(4001); 30 | -------------------------------------------------------------------------------- /benchmarks/apollo-server-express-tracing.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const cors = require("cors"); 4 | const { ApolloServer } = require("@apollo/server"); 5 | const { expressMiddleware } = require("@apollo/server/express4"); 6 | const express = require("express"); 7 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 8 | 9 | const app = express(); 10 | const schema = createApolloSchema(); 11 | const server = new ApolloServer({ 12 | schema, 13 | tracing: true, 14 | }); 15 | server.start().then(() => { 16 | app.use("/graphql", cors(), express.json(), expressMiddleware(server, {})); 17 | app.listen(4001); 18 | }); 19 | -------------------------------------------------------------------------------- /benchmarks/apollo-server-express.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const cors = require("cors"); 4 | const { ApolloServer } = require("@apollo/server"); 5 | const { expressMiddleware } = require("@apollo/server/express4"); 6 | const express = require("express"); 7 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 8 | 9 | const app = express(); 10 | const schema = createApolloSchema(); 11 | const server = new ApolloServer({ 12 | schema, 13 | }); 14 | server.start().then(() => { 15 | app.use("/graphql", cors(), express.json(), expressMiddleware(server, {})); 16 | app.listen(4001); 17 | }); 18 | -------------------------------------------------------------------------------- /benchmarks/benzene-http.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createServer } = require("http"); 4 | const { 5 | Benzene, 6 | makeHandler, 7 | parseGraphQLBody, 8 | makeCompileQuery, 9 | } = require("@benzene/http"); 10 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 11 | 12 | const rawBody = (req, done) => { 13 | let body = ""; 14 | req.on("data", (chunk) => (body += chunk)); 15 | req.on("end", () => done(body)); 16 | }; 17 | 18 | const schema = createApolloSchema(); 19 | 20 | const GQL = new Benzene({ 21 | schema, 22 | compileQuery: makeCompileQuery(), 23 | }); 24 | 25 | const graphqlHTTP = makeHandler(GQL); 26 | 27 | const server = createServer((req, res) => { 28 | rawBody(req, (rawBody) => 29 | graphqlHTTP({ 30 | method: req.method, 31 | headers: req.headers, 32 | body: parseGraphQLBody(rawBody, req.headers["content-type"]), 33 | }).then((result) => { 34 | res.writeHead(result.status, result.headers); 35 | res.end(JSON.stringify(result.payload)); 36 | }), 37 | ); 38 | }); 39 | 40 | server.listen(4001); 41 | -------------------------------------------------------------------------------- /benchmarks/benzene-jit-http.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createServer } = require("http"); 4 | const { makeCompileQuery } = require("@benzene/jit"); 5 | const { Benzene, makeHandler, parseGraphQLBody } = require("@benzene/http"); 6 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 7 | 8 | const rawBody = (req, done) => { 9 | let body = ""; 10 | req.on("data", (chunk) => (body += chunk)); 11 | req.on("end", () => done(body)); 12 | }; 13 | 14 | const schema = createApolloSchema(); 15 | 16 | const GQL = new Benzene({ 17 | schema, 18 | compileQuery: makeCompileQuery(), 19 | }); 20 | 21 | const graphqlHTTP = makeHandler(GQL); 22 | 23 | const server = createServer((req, res) => { 24 | rawBody(req, (rawBody) => 25 | graphqlHTTP({ 26 | method: req.method, 27 | headers: req.headers, 28 | body: parseGraphQLBody(rawBody, req.headers["content-type"]), 29 | }).then((result) => { 30 | res.writeHead(result.status, result.headers); 31 | res.end(JSON.stringify(result.payload)); 32 | }), 33 | ); 34 | }); 35 | 36 | server.listen(4001); 37 | -------------------------------------------------------------------------------- /benchmarks/bun-yoga-jit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const { exec } = require("child_process"); 3 | const path = require("path"); 4 | 5 | const forked = exec( 6 | "bun run server-jit.ts", 7 | { cwd: path.join(__dirname, "..", "other-benchmarks/bun/") }, 8 | (error, stdout, stderr) => { 9 | if (error) { 10 | console.log(`error: ${error.message}`); 11 | return; 12 | } 13 | if (stderr) { 14 | console.log(`stderr: ${stderr}`); 15 | return; 16 | } 17 | if (stdout) { 18 | console.log(`stdout: ${stdout}`); 19 | return; 20 | } 21 | }, 22 | ); 23 | process.on("SIGINT", () => forked.kill()); 24 | forked.on("exit", () => console.log("bun-yoga-jit exited")); 25 | -------------------------------------------------------------------------------- /benchmarks/bun-yoga.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const { exec } = require("child_process"); 3 | const path = require("path"); 4 | 5 | const forked = exec( 6 | "bun run server.ts", 7 | { cwd: path.join(__dirname, "..", "other-benchmarks/bun/") }, 8 | (error, stdout, stderr) => { 9 | if (error) { 10 | console.log(`error: ${error.message}`); 11 | return; 12 | } 13 | if (stderr) { 14 | console.log(`stderr: ${stderr}`); 15 | return; 16 | } 17 | if (stdout) { 18 | console.log(`stdout: ${stdout}`); 19 | return; 20 | } 21 | }, 22 | ); 23 | process.on("SIGINT", () => forked.kill()); 24 | forked.on("exit", () => console.log(" bun-yoga exited")); 25 | -------------------------------------------------------------------------------- /benchmarks/core-graphql-jit-buf-fjs.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createServer } = require("http"); 4 | 5 | const fastJSONStringify = require("fast-json-stringify"); 6 | const { parse } = require("graphql"); 7 | const { compileQuery } = require("graphql-jit"); 8 | const turboJSONParse = require("turbo-json-parse"); 9 | 10 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 11 | 12 | const jsonParse = turboJSONParse({ 13 | type: "object", 14 | properties: { 15 | query: { 16 | type: "string", 17 | }, 18 | }, 19 | }); 20 | 21 | const stringify = fastJSONStringify({ 22 | type: "object", 23 | properties: { 24 | data: { 25 | type: "object", 26 | properties: { 27 | authors: { 28 | type: "array", 29 | items: { 30 | type: "object", 31 | properties: { 32 | id: { 33 | type: "string", 34 | }, 35 | name: { 36 | type: "string", 37 | }, 38 | md5: { 39 | type: "string", 40 | }, 41 | books: { 42 | type: "array", 43 | items: { 44 | type: "object", 45 | properties: { 46 | id: { 47 | type: "string", 48 | }, 49 | name: { 50 | type: "string", 51 | }, 52 | }, 53 | }, 54 | }, 55 | }, 56 | }, 57 | }, 58 | }, 59 | }, 60 | }, 61 | }); 62 | 63 | const schema = createApolloSchema(); 64 | 65 | const cache = {}; 66 | 67 | const server = createServer((req, res) => { 68 | const chunks = []; 69 | 70 | req.on("data", (chunk) => { 71 | chunks.push(chunk); 72 | }); 73 | 74 | req.on("end", async () => { 75 | const { query } = jsonParse(Buffer.concat(chunks).toString()); 76 | 77 | cache[query] = cache[query] || compileQuery(schema, parse(query)); 78 | 79 | const result = await cache[query].query(); 80 | 81 | res.end(stringify(result)); 82 | }); 83 | }); 84 | 85 | server.listen(4001); 86 | -------------------------------------------------------------------------------- /benchmarks/core-graphql-jit-buf.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createServer } = require("http"); 4 | 5 | const { parse } = require("graphql"); 6 | const { compileQuery } = require("graphql-jit"); 7 | 8 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 9 | 10 | const schema = createApolloSchema(); 11 | 12 | const cache = {}; 13 | 14 | const server = createServer((req, res) => { 15 | const chunks = []; 16 | 17 | req.on("data", (chunk) => { 18 | chunks.push(chunk); 19 | }); 20 | 21 | req.on("end", async () => { 22 | const { query } = JSON.parse(Buffer.concat(chunks).toString()); 23 | 24 | cache[query] = cache[query] || compileQuery(schema, parse(query)); 25 | 26 | const result = await cache[query].query(); 27 | 28 | res.end(JSON.stringify(result)); 29 | }); 30 | }); 31 | 32 | server.listen(4001); 33 | -------------------------------------------------------------------------------- /benchmarks/core-graphql-jit-str.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createServer } = require("http"); 4 | 5 | const { parse } = require("graphql"); 6 | const { compileQuery } = require("graphql-jit"); 7 | 8 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 9 | 10 | const schema = createApolloSchema(); 11 | 12 | const cache = {}; 13 | 14 | const server = createServer((req, res) => { 15 | let payload = ""; 16 | 17 | req.on("data", (chunk) => { 18 | payload += chunk.toString(); 19 | }); 20 | 21 | req.on("end", async () => { 22 | const { query } = JSON.parse(payload); 23 | 24 | cache[query] = cache[query] || compileQuery(schema, parse(query)); 25 | 26 | const result = await cache[query].query(); 27 | 28 | res.end(JSON.stringify(result)); 29 | }); 30 | }); 31 | 32 | server.listen(4001); 33 | -------------------------------------------------------------------------------- /benchmarks/express-REST.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const express = require("express"); 4 | const graphqlUploadExpress = require("graphql-upload/graphqlUploadExpress.js"); 5 | const md5 = require("md5"); 6 | const { data } = require("../lib/data"); 7 | 8 | const app = express(); 9 | app.post("/graphql", graphqlUploadExpress(), (_, res) => { 10 | res.send(data.map((x) => ({ ...x, md5: md5(x.name) }))); 11 | }); 12 | app.listen(4001); 13 | -------------------------------------------------------------------------------- /benchmarks/express-gql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const bodyParser = require("body-parser"); 4 | const { createGraphqlMiddleware } = require("express-gql"); 5 | const express = require("express"); 6 | const graphqlUploadExpress = require("graphql-upload/graphqlUploadExpress.js"); 7 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 8 | 9 | const schema = createApolloSchema(); 10 | 11 | if (true) { 12 | throw new Error("Unsupported"); 13 | } 14 | 15 | const app = express(); 16 | app.post( 17 | "/graphql", 18 | graphqlUploadExpress(), 19 | bodyParser.json(), 20 | createGraphqlMiddleware({ 21 | context: () => ({}), 22 | formatError: ({ error }) => error, 23 | schema, 24 | }), 25 | ); 26 | app.listen(4001); 27 | -------------------------------------------------------------------------------- /benchmarks/fastify-REST.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const fastify = require("fastify")({}); 4 | const md5 = require("md5"); 5 | const { data } = require("../lib/data"); 6 | 7 | fastify.post("/graphql", (_, reply) => { 8 | reply.send(data.map((x) => ({ ...x, md5: md5(x.name) }))); 9 | }); 10 | 11 | fastify.listen(4001); 12 | -------------------------------------------------------------------------------- /benchmarks/fastify-express-graphql-jit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/fastify"); 4 | const app = require("fastify")(); 5 | 6 | const { compileQuery } = require("graphql-jit"); 7 | 8 | const { parse } = require("graphql"); 9 | 10 | const cache = {}; 11 | 12 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 13 | 14 | const schema = createApolloSchema(); 15 | 16 | if (true) { 17 | throw new Error("Unsupported"); 18 | } 19 | 20 | app.post( 21 | "/graphql", 22 | createHandler({ 23 | schema, 24 | execute: (_, __, { query }) => { 25 | if (!(query in cache)) { 26 | const document = parse(query); 27 | cache[query] = compileQuery(schema, document); 28 | } 29 | return { 30 | schema, 31 | graphiql: true, 32 | customExecuteFn: ({ rootValue, variableValues, contextValue }) => 33 | cache[query].query(rootValue, contextValue, variableValues), 34 | }; 35 | }, 36 | }), 37 | ); 38 | app.listen({ 39 | port: 4001, 40 | }); 41 | -------------------------------------------------------------------------------- /benchmarks/fastify-express-graphql-typed-jit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/fastify"); 4 | const app = require("fastify")(); 5 | const { compileQuery } = require("graphql-jit"); 6 | const { parse } = require("graphql"); 7 | const { 8 | createTypeGraphQLSchema, 9 | } = require("../lib/schemas/createTypeGraphQLSchema"); 10 | 11 | const cache = {}; 12 | 13 | if (true) { 14 | throw new Error("Unsupported"); 15 | } 16 | 17 | createTypeGraphQLSchema().then((schema) => { 18 | app.post( 19 | "/graphql", 20 | createHandler({ 21 | schema, 22 | execute: (_, __, { query }) => { 23 | if (!(query in cache)) { 24 | const document = parse(query); 25 | cache[query] = compileQuery(schema, document); 26 | } 27 | return { 28 | schema, 29 | graphiql: true, 30 | customExecuteFn: ({ rootValue, variableValues, contextValue }) => 31 | cache[query].query(rootValue, contextValue, variableValues), 32 | }; 33 | }, 34 | }), 35 | ); 36 | app.listen({ 37 | port: 4001, 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /benchmarks/fastify-express-grapql-typed.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const { 5 | createTypeGraphQLSchema, 6 | } = require("../lib/schemas/createTypeGraphQLSchema"); 7 | const app = require("fastify")(); 8 | 9 | if (true) { 10 | throw new Error("Unsupported"); 11 | } 12 | 13 | createTypeGraphQLSchema().then((schema) => { 14 | app.post( 15 | "/graphql", 16 | createHandler({ 17 | schema, 18 | async parseRequestParams(req) { 19 | const params = await processRequest(req.raw, req.context.res); 20 | if (Array.isArray(params)) { 21 | throw new Error("Batching is not supported"); 22 | } 23 | return { 24 | ...params, 25 | // variables must be an object as per the GraphQL over HTTP spec 26 | variables: Object(params.variables), 27 | }; 28 | }, 29 | }), 30 | ); 31 | app.listen({ 32 | port: 4001, 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /benchmarks/go-graphql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const { exec } = require("child_process"); 3 | const path = require("path"); 4 | 5 | const forked = exec( 6 | "go run server.go", 7 | { cwd: path.join(__dirname, "..", "other-benchmarks/go-gql/") }, 8 | (error, stdout, stderr) => { 9 | if (error) { 10 | console.log(`error: ${error.message}`); 11 | return; 12 | } 13 | if (stderr) { 14 | console.log(`stderr: ${stderr}`); 15 | return; 16 | } 17 | console.log(`stdout: ${stdout}`); 18 | }, 19 | ); 20 | console.log(path.join(__dirname, "..", "other-benchmarks/go-gql/server.go")); 21 | forked.on("exit", () => console.log("exited")); 22 | -------------------------------------------------------------------------------- /benchmarks/graphql-api-koa+graphql-jit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const Koa = require("koa"); 4 | const bodyParser = require("koa-bodyparser"); 5 | const graphqlUploadKoa = require("graphql-upload/graphqlUploadKoa.js"); 6 | const { parse } = require("graphql"); 7 | const { compileQuery } = require("graphql-jit"); 8 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 9 | 10 | const schema = createApolloSchema(); 11 | 12 | const cache = {}; 13 | 14 | Promise.all([ 15 | import("graphql-api-koa/execute.mjs"), 16 | import("graphql-api-koa/errorHandler.mjs"), 17 | ]).then(([{ default: execute }, { default: errorHandler }]) => { 18 | const app = new Koa() 19 | .use(errorHandler()) 20 | .use(graphqlUploadKoa()) 21 | .use(bodyParser()) 22 | .use( 23 | execute({ 24 | schema, 25 | override: ({ 26 | request: { 27 | body: { query }, 28 | }, 29 | }) => ({ 30 | execute({ rootValue, contextValue, variableValues }) { 31 | if (!(query in cache)) { 32 | cache[query] = compileQuery(schema, parse(query)); 33 | } 34 | return cache[query].query(rootValue, contextValue, variableValues); 35 | }, 36 | }), 37 | }), 38 | ); 39 | 40 | app.listen(4001); 41 | }); 42 | -------------------------------------------------------------------------------- /benchmarks/graphql-api-koa.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const Koa = require("koa"); 4 | const bodyParser = require("koa-bodyparser"); 5 | const graphqlUploadKoa = require("graphql-upload/graphqlUploadKoa.js"); 6 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 7 | 8 | const schema = createApolloSchema(); 9 | 10 | Promise.all([ 11 | import("graphql-api-koa/execute.mjs"), 12 | import("graphql-api-koa/errorHandler.mjs"), 13 | ]).then(([{ default: execute }, { default: errorHandler }]) => { 14 | const app = new Koa() 15 | .use(errorHandler()) 16 | .use(graphqlUploadKoa()) 17 | .use(bodyParser()) 18 | .use(execute({ schema })); 19 | 20 | app.listen(4001); 21 | }); 22 | -------------------------------------------------------------------------------- /benchmarks/graphql-compose+async.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const processRequest = require("graphql-upload/processRequest.js"); 5 | const express = require("express"); 6 | const { 7 | createAsyncGraphqlComposeSchema, 8 | } = require("../lib/schemas/createGraphqlCompose"); 9 | 10 | const app = express(); 11 | const schema = createAsyncGraphqlComposeSchema(); 12 | app.use( 13 | "/graphql", 14 | createHandler({ 15 | schema, 16 | async parseRequestParams(req) { 17 | const params = await processRequest(req.raw, req.context.res); 18 | if (Array.isArray(params)) { 19 | throw new Error("Batching is not supported"); 20 | } 21 | return { 22 | ...params, 23 | // variables must be an object as per the GraphQL over HTTP spec 24 | variables: Object(params.variables), 25 | }; 26 | }, 27 | }), 28 | ); 29 | app.listen(4001); 30 | -------------------------------------------------------------------------------- /benchmarks/graphql-http+async-middleware.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const processRequest = require("graphql-upload/processRequest.js"); 5 | const express = require("express"); 6 | const { 7 | createAsyncMiddlewareTypeGraphQLSchema, 8 | } = require("../lib/schemas/createTypeGraphQLSchema"); 9 | 10 | const app = express(); 11 | createAsyncMiddlewareTypeGraphQLSchema().then((schema) => { 12 | app.use( 13 | "/graphql", 14 | createHandler({ 15 | schema, 16 | async parseRequestParams(req) { 17 | const params = await processRequest(req.raw, req.context.res); 18 | if (Array.isArray(params)) { 19 | throw new Error("Batching is not supported"); 20 | } 21 | return { 22 | ...params, 23 | // variables must be an object as per the GraphQL over HTTP spec 24 | variables: Object(params.variables), 25 | }; 26 | }, 27 | }), 28 | ); 29 | app.listen(4001); 30 | }); 31 | -------------------------------------------------------------------------------- /benchmarks/graphql-http+async.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const processRequest = require("graphql-upload/processRequest.js"); 5 | const express = require("express"); 6 | const { 7 | createAsyncTypeGraphQLSchema, 8 | } = require("../lib/schemas/createTypeGraphQLSchema"); 9 | 10 | const app = express(); 11 | createAsyncTypeGraphQLSchema().then((schema) => { 12 | app.use( 13 | "/graphql", 14 | createHandler({ 15 | schema, 16 | async parseRequestParams(req) { 17 | const params = await processRequest(req.raw, req.context.res); 18 | if (Array.isArray(params)) { 19 | throw new Error("Batching is not supported"); 20 | } 21 | return { 22 | ...params, 23 | // variables must be an object as per the GraphQL over HTTP spec 24 | variables: Object(params.variables), 25 | }; 26 | }, 27 | }), 28 | ); 29 | app.listen(4001); 30 | }); 31 | -------------------------------------------------------------------------------- /benchmarks/graphql-http+graphql-compose.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const processRequest = require("graphql-upload/processRequest.js"); 5 | const express = require("express"); 6 | const { 7 | createGraphqlComposeSchema, 8 | } = require("../lib/schemas/createGraphqlCompose"); 9 | 10 | const app = express(); 11 | const schema = createGraphqlComposeSchema(); 12 | app.use( 13 | "/graphql", 14 | createHandler({ 15 | schema, 16 | async parseRequestParams(req) { 17 | const params = await processRequest(req.raw, req.context.res); 18 | if (Array.isArray(params)) { 19 | throw new Error("Batching is not supported"); 20 | } 21 | return { 22 | ...params, 23 | // variables must be an object as per the GraphQL over HTTP spec 24 | variables: Object(params.variables), 25 | }; 26 | }, 27 | }), 28 | ); 29 | app.listen(4001); 30 | -------------------------------------------------------------------------------- /benchmarks/graphql-http+graphql-jit+graphql-compose.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const express = require("express"); 5 | const { parse } = require("graphql"); 6 | const { compileQuery } = require("graphql-jit"); 7 | const processRequest = require("graphql-upload/processRequest.js"); 8 | const { 9 | createGraphqlComposeSchema, 10 | } = require("../lib/schemas/createGraphqlCompose"); 11 | 12 | const app = express(); 13 | 14 | const cache = {}; 15 | const schema = createGraphqlComposeSchema(); 16 | 17 | app.use( 18 | "/graphql", 19 | createHandler({ 20 | schema, 21 | async parseRequestParams(req) { 22 | const params = await processRequest(req.raw, req.context.res); 23 | if (Array.isArray(params)) { 24 | throw new Error("Batching is not supported"); 25 | } 26 | return { 27 | ...params, 28 | // variables must be an object as per the GraphQL over HTTP spec 29 | variables: Object(params.variables), 30 | }; 31 | }, 32 | execute: (_, __, { query }) => { 33 | if (!(query in cache)) { 34 | const document = parse(query); 35 | cache[query] = compileQuery(schema, document); 36 | } 37 | 38 | return { 39 | schema, 40 | customExecuteFn: ({ rootValue, variableValues, contextValue }) => 41 | cache[query].query(rootValue, contextValue, variableValues), 42 | }; 43 | }, 44 | }), 45 | ); 46 | app.listen(4001); 47 | -------------------------------------------------------------------------------- /benchmarks/graphql-http+graphql-jit+type-graphql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const express = require("express"); 5 | const { parse } = require("graphql"); 6 | const { compileQuery } = require("graphql-jit"); 7 | const processRequest = require("graphql-upload/processRequest.js"); 8 | const { 9 | createAsyncTypeGraphQLSchema, 10 | } = require("../lib/schemas/createTypeGraphQLSchema"); 11 | 12 | const app = express(); 13 | 14 | const cache = {}; 15 | 16 | createAsyncTypeGraphQLSchema().then((schema) => { 17 | app.use( 18 | "/graphql", 19 | createHandler({ 20 | schema, 21 | async parseRequestParams(req) { 22 | const params = await processRequest(req.raw, req.context.res); 23 | if (Array.isArray(params)) { 24 | throw new Error("Batching is not supported"); 25 | } 26 | return { 27 | ...params, 28 | // variables must be an object as per the GraphQL over HTTP spec 29 | variables: Object(params.variables), 30 | }; 31 | }, 32 | execute: (_, __, { query }) => { 33 | if (!(query in cache)) { 34 | const document = parse(query); 35 | cache[query] = compileQuery(schema, document); 36 | } 37 | 38 | return { 39 | schema, 40 | customExecuteFn: ({ rootValue, variableValues, contextValue }) => 41 | cache[query].query(rootValue, contextValue, variableValues), 42 | }; 43 | }, 44 | }), 45 | ); 46 | app.listen(4001); 47 | }); 48 | -------------------------------------------------------------------------------- /benchmarks/graphql-http+graphql-jit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const express = require("express"); 5 | const { parse } = require("graphql"); 6 | const { compileQuery } = require("graphql-jit"); 7 | const processRequest = require("graphql-upload/processRequest.js"); 8 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 9 | 10 | const app = express(); 11 | const schema = createApolloSchema(); 12 | 13 | const cache = {}; 14 | 15 | app.use( 16 | "/graphql", 17 | createHandler({ 18 | schema, 19 | async parseRequestParams(req) { 20 | const params = await processRequest(req.raw, req.context.res); 21 | if (Array.isArray(params)) { 22 | throw new Error("Batching is not supported"); 23 | } 24 | return { 25 | ...params, 26 | // variables must be an object as per the GraphQL over HTTP spec 27 | variables: Object(params.variables), 28 | }; 29 | }, 30 | execute: (_, __, { query }) => { 31 | if (!(query in cache)) { 32 | const document = parse(query); 33 | cache[query] = compileQuery(schema, document); 34 | } 35 | 36 | return { 37 | schema, 38 | customExecuteFn: ({ rootValue, variableValues, contextValue }) => 39 | cache[query].query(rootValue, contextValue, variableValues), 40 | }; 41 | }, 42 | }), 43 | ); 44 | app.listen(4001); 45 | -------------------------------------------------------------------------------- /benchmarks/graphql-http+middleware.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const processRequest = require("graphql-upload/processRequest.js"); 5 | const express = require("express"); 6 | const { 7 | createMiddlewareTypeGraphQLSchema, 8 | } = require("../lib/schemas/createTypeGraphQLSchema"); 9 | 10 | const app = express(); 11 | createMiddlewareTypeGraphQLSchema().then((schema) => { 12 | app.use( 13 | "/graphql", 14 | createHandler({ 15 | schema, 16 | async parseRequestParams(req) { 17 | const params = await processRequest(req.raw, req.context.res); 18 | if (Array.isArray(params)) { 19 | throw new Error("Batching is not supported"); 20 | } 21 | return { 22 | ...params, 23 | // variables must be an object as per the GraphQL over HTTP spec 24 | variables: Object(params.variables), 25 | }; 26 | }, 27 | }), 28 | ); 29 | app.listen(4001); 30 | }); 31 | -------------------------------------------------------------------------------- /benchmarks/graphql-http+type-graphql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const processRequest = require("graphql-upload/processRequest.js"); 5 | const express = require("express"); 6 | 7 | const { 8 | createTypeGraphQLSchema, 9 | } = require("../lib/schemas/createTypeGraphQLSchema"); 10 | 11 | const app = express(); 12 | createTypeGraphQLSchema().then((schema) => { 13 | app.use( 14 | "/graphql", 15 | createHandler({ 16 | schema, 17 | async parseRequestParams(req) { 18 | const params = await processRequest(req.raw, req.context.res); 19 | if (Array.isArray(params)) { 20 | throw new Error("Batching is not supported"); 21 | } 22 | return { 23 | ...params, 24 | // variables must be an object as per the GraphQL over HTTP spec 25 | variables: Object(params.variables), 26 | }; 27 | }, 28 | }), 29 | ); 30 | app.listen(4001); 31 | }); 32 | -------------------------------------------------------------------------------- /benchmarks/graphql-http-dd-trace-less.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const tracer = require("dd-trace").init(); 4 | 5 | tracer.use("graphql", { depth: 0 }); 6 | const { createHandler } = require("graphql-http/lib/use/express"); 7 | const processRequest = require("graphql-upload/processRequest.js"); 8 | const express = require("express"); 9 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 10 | 11 | const app = express(); 12 | const schema = createApolloSchema(); 13 | app.use( 14 | "/graphql", 15 | createHandler({ 16 | schema, 17 | async parseRequestParams(req) { 18 | const params = await processRequest(req.raw, req.context.res); 19 | if (Array.isArray(params)) { 20 | throw new Error("Batching is not supported"); 21 | } 22 | return { 23 | ...params, 24 | // variables must be an object as per the GraphQL over HTTP spec 25 | variables: Object(params.variables), 26 | }; 27 | }, 28 | }), 29 | ); 30 | app.listen(4001); 31 | -------------------------------------------------------------------------------- /benchmarks/graphql-http-dd-trace-no-plugin.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("dd-trace").init({ plugins: false }); 4 | const { createHandler } = require("graphql-http/lib/use/express"); 5 | const processRequest = require("graphql-upload/processRequest.js"); 6 | const express = require("express"); 7 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 8 | 9 | const app = express(); 10 | const schema = createApolloSchema(); 11 | app.use( 12 | "/graphql", 13 | createHandler({ 14 | schema, 15 | async parseRequestParams(req) { 16 | const params = await processRequest(req.raw, req.context.res); 17 | if (Array.isArray(params)) { 18 | throw new Error("Batching is not supported"); 19 | } 20 | return { 21 | ...params, 22 | // variables must be an object as per the GraphQL over HTTP spec 23 | variables: Object(params.variables), 24 | }; 25 | }, 26 | }), 27 | ); 28 | app.listen(4001); 29 | -------------------------------------------------------------------------------- /benchmarks/graphql-http-dd-trace.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("dd-trace").init(); 4 | const { createHandler } = require("graphql-http/lib/use/express"); 5 | const processRequest = require("graphql-upload/processRequest.js"); 6 | const express = require("express"); 7 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 8 | 9 | const app = express(); 10 | const schema = createApolloSchema(); 11 | app.use( 12 | "/graphql", 13 | createHandler({ 14 | schema, 15 | async parseRequestParams(req) { 16 | const params = await processRequest(req.raw, req.context.res); 17 | if (Array.isArray(params)) { 18 | throw new Error("Batching is not supported"); 19 | } 20 | return { 21 | ...params, 22 | // variables must be an object as per the GraphQL over HTTP spec 23 | variables: Object(params.variables), 24 | }; 25 | }, 26 | }), 27 | ); 28 | app.listen(4001); 29 | -------------------------------------------------------------------------------- /benchmarks/graphql-http.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createHandler } = require("graphql-http/lib/use/express"); 4 | const processRequest = require("graphql-upload/processRequest.js"); 5 | const express = require("express"); 6 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 7 | 8 | const app = express(); 9 | const schema = createApolloSchema(); 10 | app.use( 11 | "/graphql", 12 | createHandler({ 13 | schema, 14 | async parseRequestParams(req) { 15 | const params = await processRequest(req.raw, req.context.res); 16 | if (Array.isArray(params)) { 17 | throw new Error("Batching is not supported"); 18 | } 19 | return { 20 | ...params, 21 | // variables must be an object as per the GraphQL over HTTP spec 22 | variables: Object(params.variables), 23 | }; 24 | }, 25 | }), 26 | ); 27 | app.listen(4001); 28 | -------------------------------------------------------------------------------- /benchmarks/mercurius+graphql-compose.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const Fastify = require("fastify"); 4 | const mercurius = require("mercurius"); 5 | const { 6 | createGraphqlComposeSchema, 7 | } = require("../lib/schemas/createGraphqlCompose"); 8 | 9 | const schema = createGraphqlComposeSchema(); 10 | 11 | const app = Fastify(); 12 | 13 | app.register(mercurius, { 14 | schema, 15 | }); 16 | 17 | app.listen({ 18 | port: 4001, 19 | }); 20 | -------------------------------------------------------------------------------- /benchmarks/mercurius+graphql-jit+otel-instrumentation.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("../lib/instrumentations/otel-instrumentation"); 4 | const Fastify = require("fastify"); 5 | const mercurius = require("mercurius"); 6 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 7 | 8 | const schema = createApolloSchema(); 9 | 10 | const app = Fastify(); 11 | 12 | app.register(mercurius, { 13 | schema, 14 | jit: 1, 15 | }); 16 | 17 | app.listen({ 18 | port: 4001, 19 | }); 20 | -------------------------------------------------------------------------------- /benchmarks/mercurius+graphql-jit+type-graphql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const Fastify = require("fastify"); 4 | const mercurius = require("mercurius"); 5 | const { 6 | createTypeGraphQLSchema, 7 | } = require("../lib/schemas/createTypeGraphQLSchema"); 8 | 9 | const app = Fastify(); 10 | 11 | createTypeGraphQLSchema().then((schema) => { 12 | app.register(mercurius, { 13 | schema, 14 | jit: 1, 15 | }); 16 | app.listen({ 17 | port: 4001, 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /benchmarks/mercurius+graphql-jit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const Fastify = require("fastify"); 4 | const mercurius = require("mercurius"); 5 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 6 | 7 | const schema = createApolloSchema(); 8 | 9 | const app = Fastify(); 10 | 11 | app.register(mercurius, { 12 | schema, 13 | jit: 1, 14 | }); 15 | 16 | app.listen({ 17 | port: 4001, 18 | }); 19 | -------------------------------------------------------------------------------- /benchmarks/mercurius.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const Fastify = require("fastify"); 4 | const mercurius = require("mercurius"); 5 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 6 | 7 | const schema = createApolloSchema(); 8 | 9 | const app = Fastify(); 10 | 11 | app.register(mercurius, { 12 | schema, 13 | }); 14 | 15 | app.listen({ 16 | port: 4001, 17 | }); 18 | -------------------------------------------------------------------------------- /benchmarks/rust-graphql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const { exec } = require("child_process"); 3 | const path = require("path"); 4 | 5 | const forked = exec( 6 | "./target/release/rust-gql", 7 | { cwd: path.join(__dirname, "..", "other-benchmarks/rust-gql/") }, 8 | (error, stdout, stderr) => { 9 | if (error) { 10 | console.log(`error: ${error.message}`); 11 | return; 12 | } 13 | if (stderr) { 14 | console.log(`stderr: ${stderr}`); 15 | return; 16 | } 17 | console.log(`stdout: ${stdout}`); 18 | }, 19 | ); 20 | 21 | forked.on("exit", () => console.log("exited")); -------------------------------------------------------------------------------- /benchmarks/uWebSockets-graphql+jit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { parse } = require("graphql"); 4 | const { compileQuery } = require("graphql-jit"); 5 | const uws = require("uWebSockets.js"); 6 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 7 | 8 | const cache = {}; 9 | 10 | const schema = createApolloSchema(); 11 | 12 | uws 13 | .App() 14 | .post("/graphql", (res) => { 15 | readJson( 16 | res, 17 | (body) => { 18 | const { query } = body; 19 | let compiled = cache[query]; 20 | if (!compiled) { 21 | const document = parse(query); 22 | compiled = cache[query] = compileQuery(schema, document); 23 | } 24 | const ans = compiled.query({}, {}, {}); 25 | res.end(JSON.stringify(ans)); 26 | }, 27 | () => {}, 28 | ); 29 | }) 30 | .listen(4001, () => {}); 31 | 32 | function readJson(res, cb, err) { 33 | let buffer; 34 | /* Register data cb */ 35 | res.onData((ab, isLast) => { 36 | let chunk = Buffer.from(ab); 37 | if (isLast) { 38 | let json; 39 | if (buffer) { 40 | try { 41 | json = JSON.parse(Buffer.concat([buffer, chunk])); 42 | } catch (e) { 43 | /* res.close calls onAborted */ 44 | res.close(); 45 | return; 46 | } 47 | cb(json); 48 | } else { 49 | try { 50 | json = JSON.parse(chunk); 51 | } catch (e) { 52 | /* res.close calls onAborted */ 53 | res.close(); 54 | return; 55 | } 56 | cb(json); 57 | } 58 | } else { 59 | if (buffer) { 60 | buffer = Buffer.concat([buffer, chunk]); 61 | } else { 62 | buffer = Buffer.concat([chunk]); 63 | } 64 | } 65 | }); 66 | 67 | /* Register error cb */ 68 | res.onAborted(err); 69 | } 70 | -------------------------------------------------------------------------------- /benchmarks/yoga-graphql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { createServer } = require("http"); 4 | const { createYoga } = require("graphql-yoga"); 5 | const { createApolloSchema } = require("../lib/schemas/createApolloSchema"); 6 | 7 | const schema = createApolloSchema(); 8 | 9 | const yoga = createYoga({ 10 | graphqlEndpoint: "/graphql", 11 | schema, 12 | }); 13 | 14 | const server = createServer(yoga); 15 | 16 | server.listen(4001); 17 | -------------------------------------------------------------------------------- /lib/autocannon.js: -------------------------------------------------------------------------------- 1 | const autocannon = require("autocannon"); 2 | const fs = require("fs"); 3 | const compare = require("autocannon-compare"); 4 | const path = require("path"); 5 | const { promisify } = require("util"); 6 | 7 | const writeFile = promisify(fs.writeFile); 8 | const mkdir = promisify(fs.mkdir); 9 | const access = promisify(fs.access); 10 | 11 | const resultsDirectory = path.join(process.cwd(), "results"); 12 | 13 | const body = JSON.stringify({ 14 | query: 15 | "{\n authors {\n id\n name\n md5\n books {\n id\n name\n }\n }\n}", 16 | }); 17 | 18 | const run = (opts = {}) => 19 | new Promise((resolve, reject) => { 20 | autocannon( 21 | { 22 | ...opts, 23 | url: "http://localhost:4001/graphql", 24 | method: "POST", 25 | body, 26 | headers: { 27 | "content-type": "application/json", 28 | }, 29 | }, 30 | (err, result) => { 31 | if (err) { 32 | reject(err); 33 | } else { 34 | resolve(result); 35 | } 36 | }, 37 | ); 38 | }); 39 | 40 | const writeResult = async (handler, result) => { 41 | try { 42 | await access(resultsDirectory); 43 | } catch (e) { 44 | await mkdir(resultsDirectory); 45 | } 46 | 47 | result.server = handler; 48 | 49 | const dest = path.join(resultsDirectory, `${handler}.json`); 50 | return writeFile(dest, JSON.stringify(result)); 51 | }; 52 | 53 | module.exports.fire = async (opts, handler, save) => { 54 | const result = await run(opts); 55 | return save ? writeResult(handler, result) : null; 56 | }; 57 | 58 | module.exports.compare = (a, b) => { 59 | const resA = require(`${resultsDirectory}/${a}.json`); 60 | const resB = require(`${resultsDirectory}/${b}.json`); 61 | const comp = compare(resA, resB); 62 | if (comp.equal) { 63 | return true; 64 | } 65 | if (comp.aWins) { 66 | return { 67 | diff: comp.requests.difference, 68 | fastest: a, 69 | slowest: b, 70 | fastestAverage: resA.requests.average, 71 | slowestAverage: resB.requests.average, 72 | }; 73 | } 74 | return { 75 | diff: compare(resB, resA).requests.difference, 76 | fastest: b, 77 | slowest: a, 78 | fastestAverage: resB.requests.average, 79 | slowestAverage: resA.requests.average, 80 | }; 81 | }; 82 | -------------------------------------------------------------------------------- /lib/bench.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { fork } = require("child_process"); 4 | const path = require("path"); 5 | const { fire } = require("./autocannon"); 6 | 7 | const doBench = async (opts, handler) => { 8 | const { default: ora } = await import("ora"); 9 | const spinner = ora(`Started ${handler}`).start(); 10 | const forked = fork(path.join(__dirname, "..", "benchmarks", handler)); 11 | try { 12 | spinner.color = "magenta"; 13 | spinner.text = `Warming ${handler}`; 14 | await fire(opts, handler, false); 15 | } catch (error) { 16 | return console.log(error); 17 | } finally { 18 | spinner.color = "yellow"; 19 | spinner.text = `Working ${handler}`; 20 | } 21 | 22 | try { 23 | await fire(opts, handler, true); 24 | forked.kill("SIGINT"); 25 | spinner.text = `Results saved for ${handler}`; 26 | spinner.succeed(); 27 | return true; 28 | } catch (error) { 29 | return console.log(error); 30 | } 31 | }; 32 | 33 | let index = 0; 34 | const start = async (opts, list) => { 35 | if (list.length === index) { 36 | return true; 37 | } 38 | 39 | try { 40 | await doBench(opts, list[index]); 41 | index += 1; 42 | return start(opts, list); 43 | } catch (error) { 44 | return console.log(error); 45 | } 46 | }; 47 | 48 | module.exports = start; 49 | -------------------------------------------------------------------------------- /lib/choices.js: -------------------------------------------------------------------------------- 1 | const { readdirSync } = require("fs"); 2 | const { join } = require("path"); 3 | 4 | module.exports.choices = readdirSync(join(__dirname, "..", "benchmarks")).map( 5 | (x) => x.replace(".js", ""), 6 | ); 7 | -------------------------------------------------------------------------------- /lib/data.js: -------------------------------------------------------------------------------- 1 | const { faker } = require("@faker-js/faker"); 2 | 3 | // that way data is consistent 4 | faker.seed(4321); 5 | 6 | function genData() { 7 | const authors = []; 8 | for (let i = 0; i < 20; i++) { 9 | const books = []; 10 | 11 | for (let k = 0; k < 3; k++) { 12 | books.push({ 13 | id: faker.string.uuid(), 14 | name: faker.internet.domainName(), 15 | numPages: faker.number.int(), 16 | }); 17 | } 18 | 19 | authors.push({ 20 | id: faker.string.uuid(), 21 | name: faker.person.fullName(), 22 | company: faker.company.buzzPhrase(), 23 | books, 24 | }); 25 | } 26 | 27 | return authors; 28 | } 29 | 30 | module.exports.data = genData(); 31 | -------------------------------------------------------------------------------- /lib/instrumentations/otel-instrumentation.js: -------------------------------------------------------------------------------- 1 | const { registerInstrumentations } = require("@opentelemetry/instrumentation"); 2 | const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); 3 | const { 4 | SemanticResourceAttributes, 5 | } = require("@opentelemetry/semantic-conventions"); 6 | const { Resource } = require("@opentelemetry/resources"); 7 | const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base"); 8 | const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http"); 9 | const { 10 | FastifyInstrumentation, 11 | } = require("@opentelemetry/instrumentation-fastify"); 12 | const { 13 | GraphQLInstrumentation, 14 | } = require("@opentelemetry/instrumentation-graphql"); 15 | const { 16 | OTLPTraceExporter, 17 | } = require("@opentelemetry/exporter-trace-otlp-grpc"); 18 | 19 | const provider = new NodeTracerProvider({ 20 | resource: new Resource({ 21 | [SemanticResourceAttributes.SERVICE_NAME]: "graphql-service", 22 | }), 23 | }); 24 | 25 | provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter())); 26 | provider.register(); 27 | 28 | registerInstrumentations({ 29 | instrumentations: [ 30 | new GraphQLInstrumentation({}), 31 | new HttpInstrumentation(), 32 | new FastifyInstrumentation(), 33 | ], 34 | }); 35 | -------------------------------------------------------------------------------- /lib/schemas/createApolloSchema.js: -------------------------------------------------------------------------------- 1 | const { makeExecutableSchema } = require("@graphql-tools/schema"); 2 | const md5 = require("md5"); 3 | const { gql } = require("graphql-tag"); 4 | const { data } = require("../data"); 5 | 6 | const typeDefs = gql` 7 | type Author { 8 | id: ID! 9 | name: String! 10 | md5: String! 11 | company: String! 12 | books: [Book!]! 13 | } 14 | 15 | type Book { 16 | id: ID! 17 | name: String! 18 | numPages: Int! 19 | } 20 | 21 | type Query { 22 | authors: [Author!]! 23 | } 24 | `; 25 | 26 | const resolvers = { 27 | Author: { 28 | md5: (parent) => md5(parent.name), 29 | }, 30 | Query: { 31 | authors: () => data, 32 | }, 33 | }; 34 | 35 | const asyncResolvers = { 36 | Author: { 37 | md5: (parent) => md5(parent.name), 38 | }, 39 | Query: { 40 | authors: async () => data, 41 | }, 42 | }; 43 | 44 | module.exports.createApolloSchema = () => 45 | makeExecutableSchema({ 46 | typeDefs, 47 | resolvers, 48 | }); 49 | 50 | module.exports.createAsyncApolloSchema = () => 51 | makeExecutableSchema({ 52 | typeDefs, 53 | resolvers: asyncResolvers, 54 | }); 55 | -------------------------------------------------------------------------------- /lib/schemas/createGraphqlCompose.js: -------------------------------------------------------------------------------- 1 | const { SchemaComposer } = require("graphql-compose"); 2 | const md5 = require("md5"); 3 | const { data } = require("../data"); 4 | 5 | const sc = new SchemaComposer(); 6 | 7 | sc.createObjectTC({ 8 | name: "Author", 9 | fields: { 10 | id: "ID!", 11 | name: "String!", 12 | md5: { 13 | type: "String!", 14 | resolve: (parent) => md5(parent.name), 15 | }, 16 | company: "String!", 17 | books: "[Book!]!", 18 | }, 19 | }); 20 | 21 | sc.createObjectTC({ 22 | name: "Book", 23 | fields: { 24 | id: "ID!", 25 | name: "String!", 26 | numPages: "Int!", 27 | }, 28 | }); 29 | 30 | sc.Query.addFields({ 31 | authors: { 32 | type: "[Author!]!", 33 | resolve: () => data, 34 | }, 35 | }); 36 | 37 | module.exports.createGraphqlComposeSchema = () => sc.buildSchema(); 38 | 39 | module.exports.createAsyncGraphqlComposeSchema = () => { 40 | // clone Schema and override resolve method for `Query.authors` field 41 | const sc2 = sc.clone(); 42 | sc2.Query.extendField("authors", { 43 | resolve: async () => data, 44 | }); 45 | 46 | return sc2.buildSchema(); 47 | }; 48 | -------------------------------------------------------------------------------- /lib/schemas/createTypeGraphQLSchema.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | var __param = (this && this.__param) || function (paramIndex, decorator) { 12 | return function (target, key) { decorator(target, key, paramIndex); } 13 | }; 14 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 15 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 16 | return new (P || (P = Promise))(function (resolve, reject) { 17 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 18 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 19 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 20 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 21 | }); 22 | }; 23 | Object.defineProperty(exports, "__esModule", { value: true }); 24 | exports.createAsyncMiddlewareTypeGraphQLSchema = exports.createMiddlewareTypeGraphQLSchema = exports.createAsyncTypeGraphQLSchema = exports.createTypeGraphQLSchema = void 0; 25 | require("reflect-metadata"); 26 | const type_graphql_1 = require("type-graphql"); 27 | const data_1 = require("../data"); 28 | const md5 = require("md5"); 29 | let Book = class Book { 30 | }; 31 | __decorate([ 32 | (0, type_graphql_1.Field)(() => type_graphql_1.ID), 33 | __metadata("design:type", String) 34 | ], Book.prototype, "id", void 0); 35 | __decorate([ 36 | (0, type_graphql_1.Field)(), 37 | __metadata("design:type", String) 38 | ], Book.prototype, "name", void 0); 39 | __decorate([ 40 | (0, type_graphql_1.Field)(() => type_graphql_1.Int), 41 | __metadata("design:type", Number) 42 | ], Book.prototype, "numPages", void 0); 43 | Book = __decorate([ 44 | (0, type_graphql_1.ObjectType)() 45 | ], Book); 46 | let Author = class Author { 47 | }; 48 | __decorate([ 49 | (0, type_graphql_1.Field)(() => type_graphql_1.ID), 50 | __metadata("design:type", String) 51 | ], Author.prototype, "id", void 0); 52 | __decorate([ 53 | (0, type_graphql_1.Field)(), 54 | __metadata("design:type", String) 55 | ], Author.prototype, "name", void 0); 56 | __decorate([ 57 | (0, type_graphql_1.Field)(), 58 | __metadata("design:type", String) 59 | ], Author.prototype, "md5", void 0); 60 | __decorate([ 61 | (0, type_graphql_1.Field)(), 62 | __metadata("design:type", String) 63 | ], Author.prototype, "company", void 0); 64 | __decorate([ 65 | (0, type_graphql_1.Field)(() => [Book]), 66 | __metadata("design:type", Array) 67 | ], Author.prototype, "books", void 0); 68 | Author = __decorate([ 69 | (0, type_graphql_1.ObjectType)() 70 | ], Author); 71 | let SimpleResolver = class SimpleResolver { 72 | md5(root) { 73 | return md5(root.name); 74 | } 75 | authors() { 76 | return data_1.data; 77 | } 78 | }; 79 | __decorate([ 80 | (0, type_graphql_1.FieldResolver)(), 81 | __param(0, (0, type_graphql_1.Root)()), 82 | __metadata("design:type", Function), 83 | __metadata("design:paramtypes", [Author]), 84 | __metadata("design:returntype", void 0) 85 | ], SimpleResolver.prototype, "md5", null); 86 | __decorate([ 87 | (0, type_graphql_1.Query)(() => [Author]), 88 | __metadata("design:type", Function), 89 | __metadata("design:paramtypes", []), 90 | __metadata("design:returntype", void 0) 91 | ], SimpleResolver.prototype, "authors", null); 92 | SimpleResolver = __decorate([ 93 | (0, type_graphql_1.Resolver)(Author) 94 | ], SimpleResolver); 95 | let AsyncResolver = class AsyncResolver { 96 | md5(root) { 97 | return md5(root.name); 98 | } 99 | authors() { 100 | return __awaiter(this, void 0, void 0, function* () { 101 | return data_1.data; 102 | }); 103 | } 104 | }; 105 | __decorate([ 106 | (0, type_graphql_1.FieldResolver)(), 107 | __param(0, (0, type_graphql_1.Root)()), 108 | __metadata("design:type", Function), 109 | __metadata("design:paramtypes", [Author]), 110 | __metadata("design:returntype", void 0) 111 | ], AsyncResolver.prototype, "md5", null); 112 | __decorate([ 113 | (0, type_graphql_1.Query)(() => [Author]), 114 | __metadata("design:type", Function), 115 | __metadata("design:paramtypes", []), 116 | __metadata("design:returntype", Promise) 117 | ], AsyncResolver.prototype, "authors", null); 118 | AsyncResolver = __decorate([ 119 | (0, type_graphql_1.Resolver)(Author) 120 | ], AsyncResolver); 121 | let MiddlewareResolver = class MiddlewareResolver { 122 | md5(root) { 123 | return md5(root.name); 124 | } 125 | authors() { 126 | return __awaiter(this, void 0, void 0, function* () { 127 | return data_1.data; 128 | }); 129 | } 130 | }; 131 | __decorate([ 132 | (0, type_graphql_1.FieldResolver)(), 133 | __param(0, (0, type_graphql_1.Root)()), 134 | __metadata("design:type", Function), 135 | __metadata("design:paramtypes", [Author]), 136 | __metadata("design:returntype", void 0) 137 | ], MiddlewareResolver.prototype, "md5", null); 138 | __decorate([ 139 | (0, type_graphql_1.Query)(() => [Author]), 140 | (0, type_graphql_1.UseMiddleware)(({ args }, next) => { 141 | Object.keys(args).length; 142 | return next(); 143 | }), 144 | __metadata("design:type", Function), 145 | __metadata("design:paramtypes", []), 146 | __metadata("design:returntype", Promise) 147 | ], MiddlewareResolver.prototype, "authors", null); 148 | MiddlewareResolver = __decorate([ 149 | (0, type_graphql_1.Resolver)(Author) 150 | ], MiddlewareResolver); 151 | let AsyncMiddlewareResolver = class AsyncMiddlewareResolver { 152 | md5(root) { 153 | return md5(root.name); 154 | } 155 | authors() { 156 | return __awaiter(this, void 0, void 0, function* () { 157 | return data_1.data; 158 | }); 159 | } 160 | }; 161 | __decorate([ 162 | (0, type_graphql_1.FieldResolver)(), 163 | __param(0, (0, type_graphql_1.Root)()), 164 | __metadata("design:type", Function), 165 | __metadata("design:paramtypes", [Author]), 166 | __metadata("design:returntype", void 0) 167 | ], AsyncMiddlewareResolver.prototype, "md5", null); 168 | __decorate([ 169 | (0, type_graphql_1.Query)(() => [Author]), 170 | (0, type_graphql_1.UseMiddleware)((_a, next_1) => __awaiter(void 0, [_a, next_1], void 0, function* ({ args }, next) { 171 | Object.keys(args).length; 172 | return next(); 173 | })), 174 | __metadata("design:type", Function), 175 | __metadata("design:paramtypes", []), 176 | __metadata("design:returntype", Promise) 177 | ], AsyncMiddlewareResolver.prototype, "authors", null); 178 | AsyncMiddlewareResolver = __decorate([ 179 | (0, type_graphql_1.Resolver)(Author) 180 | ], AsyncMiddlewareResolver); 181 | function createTypeGraphQLSchema() { 182 | return (0, type_graphql_1.buildSchema)({ 183 | resolvers: [SimpleResolver], 184 | }); 185 | } 186 | exports.createTypeGraphQLSchema = createTypeGraphQLSchema; 187 | function createAsyncTypeGraphQLSchema() { 188 | return (0, type_graphql_1.buildSchema)({ 189 | resolvers: [AsyncResolver], 190 | }); 191 | } 192 | exports.createAsyncTypeGraphQLSchema = createAsyncTypeGraphQLSchema; 193 | function createMiddlewareTypeGraphQLSchema() { 194 | return (0, type_graphql_1.buildSchema)({ 195 | resolvers: [MiddlewareResolver], 196 | }); 197 | } 198 | exports.createMiddlewareTypeGraphQLSchema = createMiddlewareTypeGraphQLSchema; 199 | function createAsyncMiddlewareTypeGraphQLSchema() { 200 | return (0, type_graphql_1.buildSchema)({ 201 | resolvers: [AsyncMiddlewareResolver], 202 | }); 203 | } 204 | exports.createAsyncMiddlewareTypeGraphQLSchema = createAsyncMiddlewareTypeGraphQLSchema; 205 | //# sourceMappingURL=createTypeGraphQLSchema.js.map -------------------------------------------------------------------------------- /lib/schemas/createTypeGraphQLSchema.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | import { 3 | buildSchema, 4 | Resolver, 5 | Query, 6 | ObjectType, 7 | Field, 8 | Int, 9 | ID, 10 | FieldResolver, 11 | Root, 12 | UseMiddleware, 13 | } from "type-graphql"; 14 | import { data } from "../data"; 15 | import md5 = require("md5"); 16 | 17 | @ObjectType() 18 | class Book { 19 | @Field(() => ID) 20 | id: string; 21 | @Field() 22 | name: string; 23 | @Field(() => Int) 24 | numPages: number; 25 | } 26 | 27 | @ObjectType() 28 | class Author { 29 | @Field(() => ID) 30 | id: string; 31 | @Field() 32 | name: string; 33 | @Field() 34 | md5: string; 35 | @Field() 36 | company: string; 37 | @Field(() => [Book]) 38 | books: Book[]; 39 | } 40 | 41 | @Resolver(Author) 42 | class SimpleResolver { 43 | @FieldResolver() 44 | md5(@Root() root: Author) { 45 | return md5(root.name); 46 | } 47 | @Query(() => [Author]) 48 | authors() { 49 | return data; 50 | } 51 | } 52 | 53 | @Resolver(Author) 54 | class AsyncResolver { 55 | @FieldResolver() 56 | md5(@Root() root: Author) { 57 | return md5(root.name); 58 | } 59 | @Query(() => [Author]) 60 | async authors() { 61 | return data; 62 | } 63 | } 64 | 65 | @Resolver(Author) 66 | class MiddlewareResolver { 67 | @FieldResolver() 68 | md5(@Root() root: Author) { 69 | return md5(root.name); 70 | } 71 | @Query(() => [Author]) 72 | @UseMiddleware(({ args }, next) => { 73 | Object.keys(args).length; 74 | return next(); 75 | }) 76 | async authors() { 77 | return data; 78 | } 79 | } 80 | 81 | @Resolver(Author) 82 | class AsyncMiddlewareResolver { 83 | @FieldResolver() 84 | md5(@Root() root: Author) { 85 | return md5(root.name); 86 | } 87 | @Query(() => [Author]) 88 | @UseMiddleware(async ({ args }, next) => { 89 | Object.keys(args).length; 90 | return next(); 91 | }) 92 | async authors() { 93 | return data; 94 | } 95 | } 96 | 97 | export function createTypeGraphQLSchema() { 98 | return buildSchema({ 99 | resolvers: [SimpleResolver], 100 | }); 101 | } 102 | 103 | export function createAsyncTypeGraphQLSchema() { 104 | return buildSchema({ 105 | resolvers: [AsyncResolver], 106 | }); 107 | } 108 | 109 | export function createMiddlewareTypeGraphQLSchema() { 110 | return buildSchema({ 111 | resolvers: [MiddlewareResolver], 112 | }); 113 | } 114 | 115 | export function createAsyncMiddlewareTypeGraphQLSchema() { 116 | return buildSchema({ 117 | resolvers: [AsyncMiddlewareResolver], 118 | }); 119 | } 120 | -------------------------------------------------------------------------------- /other-benchmarks/bun/.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | 15 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 16 | 17 | # Runtime data 18 | 19 | pids 20 | _.pid 21 | _.seed 22 | \*.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | 30 | coverage 31 | \*.lcov 32 | 33 | # nyc test coverage 34 | 35 | .nyc_output 36 | 37 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 38 | 39 | .grunt 40 | 41 | # Bower dependency directory (https://bower.io/) 42 | 43 | bower_components 44 | 45 | # node-waf configuration 46 | 47 | .lock-wscript 48 | 49 | # Compiled binary addons (https://nodejs.org/api/addons.html) 50 | 51 | build/Release 52 | 53 | # Dependency directories 54 | 55 | node_modules/ 56 | jspm_packages/ 57 | 58 | # Snowpack dependency directory (https://snowpack.dev/) 59 | 60 | web_modules/ 61 | 62 | # TypeScript cache 63 | 64 | \*.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | 68 | .npm 69 | 70 | # Optional eslint cache 71 | 72 | .eslintcache 73 | 74 | # Optional stylelint cache 75 | 76 | .stylelintcache 77 | 78 | # Microbundle cache 79 | 80 | .rpt2_cache/ 81 | .rts2_cache_cjs/ 82 | .rts2_cache_es/ 83 | .rts2_cache_umd/ 84 | 85 | # Optional REPL history 86 | 87 | .node_repl_history 88 | 89 | # Output of 'npm pack' 90 | 91 | \*.tgz 92 | 93 | # Yarn Integrity file 94 | 95 | .yarn-integrity 96 | 97 | # dotenv environment variable files 98 | 99 | .env 100 | .env.development.local 101 | .env.test.local 102 | .env.production.local 103 | .env.local 104 | 105 | # parcel-bundler cache (https://parceljs.org/) 106 | 107 | .cache 108 | .parcel-cache 109 | 110 | # Next.js build output 111 | 112 | .next 113 | out 114 | 115 | # Nuxt.js build / generate output 116 | 117 | .nuxt 118 | dist 119 | 120 | # Gatsby files 121 | 122 | .cache/ 123 | 124 | # Comment in the public line in if your project uses Gatsby and not Next.js 125 | 126 | # https://nextjs.org/blog/next-9-1#public-directory-support 127 | 128 | # public 129 | 130 | # vuepress build output 131 | 132 | .vuepress/dist 133 | 134 | # vuepress v2.x temp and cache directory 135 | 136 | .temp 137 | .cache 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.\* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | -------------------------------------------------------------------------------- /other-benchmarks/bun/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "trailingComma": "all", 5 | "bracketSpacing": true, 6 | "semi": true, 7 | "useTabs": false, 8 | "jsxBracketSameLine": true, 9 | "endOfLine": "auto" 10 | } 11 | -------------------------------------------------------------------------------- /other-benchmarks/bun/README.md: -------------------------------------------------------------------------------- 1 | # bun-graphql-benchmark 2 | 3 | To install dependencies: 4 | 5 | ```bash 6 | bun install 7 | ``` 8 | 9 | To run: 10 | 11 | ```bash 12 | bun run server.ts 13 | ``` 14 | 15 | This project was created using `bun init` in bun v1.0.3. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. 16 | -------------------------------------------------------------------------------- /other-benchmarks/bun/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benawad/node-graphql-benchmarks/ed5547b5245d590ff5102346004717b6d2783571/other-benchmarks/bun/bun.lockb -------------------------------------------------------------------------------- /other-benchmarks/bun/data.ts: -------------------------------------------------------------------------------- 1 | import { faker } from "@faker-js/faker"; 2 | 3 | // that way data is consistent 4 | faker.seed(4321); 5 | 6 | function genData() { 7 | const authors = []; 8 | for (let i = 0; i < 20; i++) { 9 | const books = []; 10 | 11 | for (let k = 0; k < 3; k++) { 12 | books.push({ 13 | id: faker.string.uuid(), 14 | name: faker.internet.domainName(), 15 | numPages: faker.number.int(), 16 | }); 17 | } 18 | 19 | authors.push({ 20 | id: faker.string.uuid(), 21 | name: faker.person.fullName(), 22 | company: faker.company.buzzPhrase(), 23 | books, 24 | }); 25 | } 26 | 27 | return authors; 28 | } 29 | 30 | export const data = genData(); 31 | -------------------------------------------------------------------------------- /other-benchmarks/bun/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bun-graphql-benchmark", 3 | "module": "server.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "bun-types": "latest", 7 | "prettier": "^3.2.5" 8 | }, 9 | "peerDependencies": { 10 | "typescript": "^5.0.0" 11 | }, 12 | "dependencies": { 13 | "@envelop/graphql-jit": "^8.0.3", 14 | "@faker-js/faker": "^8.4.1", 15 | "graphql": "^16.8.1", 16 | "graphql-yoga": "^5.3.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /other-benchmarks/bun/schema.ts: -------------------------------------------------------------------------------- 1 | import { createSchema } from "graphql-yoga"; 2 | 3 | const md5hasher = new Bun.CryptoHasher("md5"); 4 | 5 | import { data } from "./data"; 6 | 7 | type Book = { 8 | id: string; 9 | name: string; 10 | numPages: number; 11 | }; 12 | 13 | type Author = { 14 | id: string; 15 | name: string; 16 | md5: string; 17 | company: string; 18 | books: Book[]; 19 | }; 20 | 21 | const schema = createSchema({ 22 | typeDefs: ` 23 | type Author { 24 | id: ID! 25 | name: String! 26 | md5: String! 27 | company: String! 28 | books: [Book!]! 29 | } 30 | 31 | type Book { 32 | id: ID! 33 | name: String! 34 | numPages: Int! 35 | } 36 | 37 | type Query { 38 | authors: [Author!]! 39 | }`, 40 | resolvers: { 41 | Author: { 42 | md5: (parent: Author) => md5hasher.update(parent.name).digest("hex"), 43 | }, 44 | Query: { 45 | authors: () => data, 46 | }, 47 | }, 48 | }); 49 | 50 | export default schema; 51 | -------------------------------------------------------------------------------- /other-benchmarks/bun/server-jit.ts: -------------------------------------------------------------------------------- 1 | import { createYoga } from "graphql-yoga"; 2 | import { useGraphQlJit } from "@envelop/graphql-jit"; 3 | 4 | import schema from "./schema"; 5 | 6 | const fetch = createYoga({ 7 | graphqlEndpoint: "/graphql", 8 | schema, 9 | plugins: [useGraphQlJit()], 10 | }); 11 | 12 | const server = Bun.serve({ 13 | fetch, 14 | port: process.env.PORT || 4001, 15 | }); 16 | 17 | process.on("SIGINT", (code) => { 18 | server.stop(true); 19 | process.exit(0); 20 | }); 21 | 22 | process.on("SIGTERM", (code) => { 23 | server.stop(true); 24 | process.exit(0); 25 | }); 26 | -------------------------------------------------------------------------------- /other-benchmarks/bun/server.ts: -------------------------------------------------------------------------------- 1 | import { createYoga } from "graphql-yoga"; 2 | 3 | import schema from "./schema"; 4 | 5 | const fetch = createYoga({ 6 | graphqlEndpoint: "/graphql", 7 | schema, 8 | }); 9 | 10 | const server = Bun.serve({ 11 | fetch, 12 | port: process.env.PORT || 4001, 13 | }); 14 | 15 | process.on("SIGINT", (code) => { 16 | server.stop(true); 17 | process.exit(0); 18 | }); 19 | 20 | process.on("SIGTERM", (code) => { 21 | server.stop(true); 22 | process.exit(0); 23 | }); 24 | -------------------------------------------------------------------------------- /other-benchmarks/bun/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "esnext", 5 | "target": "esnext", 6 | "moduleResolution": "bundler", 7 | "moduleDetection": "force", 8 | "allowImportingTsExtensions": true, 9 | "noEmit": true, 10 | "composite": true, 11 | "strict": true, 12 | "downlevelIteration": true, 13 | "skipLibCheck": true, 14 | "jsx": "react-jsx", 15 | "allowSyntheticDefaultImports": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "allowJs": true, 18 | "types": [ 19 | "bun-types" // add Bun global 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /other-benchmarks/go-gql/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/fibs7000/go-graphql-benchmark 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/99designs/gqlgen v0.17.31 7 | github.com/jaswdr/faker v1.19.1 8 | github.com/vektah/gqlparser/v2 v2.5.7 9 | ) 10 | 11 | require ( 12 | github.com/agnivade/levenshtein v1.1.1 // indirect 13 | github.com/gorilla/websocket v1.5.0 // indirect 14 | github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect 15 | github.com/mitchellh/mapstructure v1.5.0 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /other-benchmarks/go-gql/go.sum: -------------------------------------------------------------------------------- 1 | github.com/99designs/gqlgen v0.17.31 h1:VncSQ82VxieHkea8tz11p7h/zSbvHSxSDZfywqWt158= 2 | github.com/99designs/gqlgen v0.17.31/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= 3 | github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= 4 | github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= 5 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= 6 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= 7 | github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= 8 | github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= 9 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 10 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 11 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 12 | github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= 13 | github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= 14 | github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= 15 | github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 16 | github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= 17 | github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= 18 | github.com/jaswdr/faker v1.19.1 h1:xBoz8/O6r0QAR8eEvKJZMdofxiRH+F0M/7MU9eNKhsM= 19 | github.com/jaswdr/faker v1.19.1/go.mod h1:x7ZlyB1AZqwqKZgyQlnqEG8FDptmHlncA5u2zY/yi6w= 20 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 21 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 22 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 23 | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= 24 | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 25 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 26 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 27 | github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= 28 | github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= 29 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 30 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 31 | github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= 32 | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 33 | github.com/vektah/gqlparser/v2 v2.5.7 h1:QnW4lWFSaycZ1jqvVaQ/tDXGGzQfqAuWdyC4S9g/KVM= 34 | github.com/vektah/gqlparser/v2 v2.5.7/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= 35 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 36 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 37 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 38 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 39 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 40 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 41 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 42 | -------------------------------------------------------------------------------- /other-benchmarks/go-gql/gqlgen.yml: -------------------------------------------------------------------------------- 1 | # Where are all the schema files located? globs are supported eg src/**/*.graphqls 2 | schema: 3 | - graph/*.graphqls 4 | 5 | # Where should the generated server code go? 6 | exec: 7 | filename: graph/generated/generated.go 8 | package: generated 9 | 10 | # Uncomment to enable federation 11 | # federation: 12 | # filename: graph/generated/federation.go 13 | # package: generated 14 | 15 | # Where should any generated models go? 16 | model: 17 | filename: graph/model/models_gen.go 18 | package: model 19 | 20 | # Where should the resolver implementations go? 21 | resolver: 22 | layout: follow-schema 23 | dir: graph 24 | package: graph 25 | 26 | # Optional: turn on use `gqlgen:"fieldName"` tags in your models 27 | # struct_tag: json 28 | 29 | # Optional: turn on to use []Thing instead of []*Thing 30 | # omit_slice_element_pointers: false 31 | 32 | # Optional: set to speed up generation time by not performing a final validation pass. 33 | # skip_validation: true 34 | 35 | # gqlgen will search for any type names in the schema in these go packages 36 | # if they match it will use them, otherwise it will generate them. 37 | autobind: 38 | - "github.com/fibs7000/go-graphql-benchmark/graph/model" 39 | 40 | # This section declares type mapping between the GraphQL and go type systems 41 | # 42 | # The first line in each type will be used as defaults for resolver arguments and 43 | # modelgen, the others will be allowed when binding to fields. Configure them to 44 | # your liking 45 | models: 46 | ID: 47 | model: 48 | - github.com/99designs/gqlgen/graphql.ID 49 | - github.com/99designs/gqlgen/graphql.Int 50 | - github.com/99designs/gqlgen/graphql.Int64 51 | - github.com/99designs/gqlgen/graphql.Int32 52 | Int: 53 | model: 54 | - github.com/99designs/gqlgen/graphql.Int 55 | - github.com/99designs/gqlgen/graphql.Int64 56 | - github.com/99designs/gqlgen/graphql.Int32 57 | -------------------------------------------------------------------------------- /other-benchmarks/go-gql/graph/model/models_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. 2 | 3 | package model 4 | 5 | type Author struct { 6 | ID string `json:"id"` 7 | Name string `json:"name"` 8 | Md5 string `json:"md5"` 9 | Company string `json:"company"` 10 | Books []*Book `json:"books"` 11 | } 12 | 13 | type Book struct { 14 | ID string `json:"id"` 15 | Name string `json:"name"` 16 | NumPages int `json:"numPages"` 17 | } 18 | -------------------------------------------------------------------------------- /other-benchmarks/go-gql/graph/resolver.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | // This file will not be regenerated automatically. 4 | // 5 | // It serves as dependency injection for your app, add any dependencies you require here. 6 | 7 | type Resolver struct{} 8 | -------------------------------------------------------------------------------- /other-benchmarks/go-gql/graph/schema.graphqls: -------------------------------------------------------------------------------- 1 | # GraphQL schema example 2 | # 3 | # https://gqlgen.com/getting-started/ 4 | 5 | type Author { 6 | id: ID! 7 | name: String! 8 | md5: String! @goField(forceResolver: true) 9 | company: String! 10 | books: [Book!]! 11 | } 12 | 13 | type Book { 14 | id: ID! 15 | name: String! 16 | numPages: Int! 17 | } 18 | 19 | type Query { 20 | authors: [Author!]! 21 | } 22 | 23 | directive @goField(forceResolver: Boolean, name: String) on INPUT_FIELD_DEFINITION 24 | | FIELD_DEFINITION -------------------------------------------------------------------------------- /other-benchmarks/go-gql/graph/schema.resolvers.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | // This file will be automatically regenerated based on the schema, any resolver implementations 4 | // will be copied through when generating and any unknown code will be moved to the end. 5 | 6 | import ( 7 | "context" 8 | "crypto/md5" 9 | "encoding/hex" 10 | 11 | "github.com/fibs7000/go-graphql-benchmark/graph/generated" 12 | "github.com/fibs7000/go-graphql-benchmark/graph/model" 13 | "github.com/fibs7000/go-graphql-benchmark/src/data" 14 | ) 15 | 16 | func (r *authorResolver) Md5(ctx context.Context, obj *model.Author) (string, error) { 17 | 18 | return GetMD5Hash(obj.Name), nil 19 | } 20 | 21 | func (r *queryResolver) Authors(ctx context.Context) ([]*model.Author, error) { 22 | return data.GenData(), nil 23 | } 24 | 25 | // Author returns generated.AuthorResolver implementation. 26 | func (r *Resolver) Author() generated.AuthorResolver { return &authorResolver{r} } 27 | 28 | // Query returns generated.QueryResolver implementation. 29 | func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } 30 | 31 | type authorResolver struct{ *Resolver } 32 | type queryResolver struct{ *Resolver } 33 | 34 | func GetMD5Hash(text string) string { 35 | hash := md5.Sum([]byte(text)) 36 | return hex.EncodeToString(hash[:]) 37 | } 38 | -------------------------------------------------------------------------------- /other-benchmarks/go-gql/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "os" 7 | 8 | "github.com/99designs/gqlgen/graphql/handler" 9 | "github.com/99designs/gqlgen/graphql/playground" 10 | "github.com/fibs7000/go-graphql-benchmark/graph" 11 | "github.com/fibs7000/go-graphql-benchmark/graph/generated" 12 | ) 13 | 14 | const defaultPort = "4001" 15 | 16 | func main() { 17 | port := os.Getenv("PORT") 18 | if port == "" { 19 | port = defaultPort 20 | } 21 | 22 | srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}})) 23 | 24 | http.Handle("/", playground.Handler("GraphQL playground", "/graphql")) 25 | http.Handle("/graphql", srv) 26 | 27 | log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) 28 | log.Fatal(http.ListenAndServe(":"+port, nil)) 29 | } 30 | -------------------------------------------------------------------------------- /other-benchmarks/go-gql/src/data/data.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "github.com/fibs7000/go-graphql-benchmark/graph/model" 5 | "github.com/jaswdr/faker" 6 | ) 7 | 8 | func GenData() []*model.Author { 9 | faker := faker.New() 10 | 11 | var authors []*model.Author 12 | for i := 0; i < 20; i++ { 13 | var books []*model.Book 14 | 15 | for k := 0; k < 3; k++ { 16 | book := model.Book{ 17 | ID: faker.UUID().V4(), 18 | Name: faker.Person().LastName(), 19 | NumPages: faker.IntBetween(100, 10000), 20 | } 21 | books = append(books, &book) 22 | } 23 | 24 | author := model.Author{ 25 | ID: faker.UUID().V4(), 26 | Name: faker.Person().FirstName(), 27 | Company: faker.Company().BS(), 28 | Books: books, 29 | } 30 | authors = append(authors, &author) 31 | } 32 | 33 | return authors 34 | } 35 | -------------------------------------------------------------------------------- /other-benchmarks/rust-gql/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "Inflector" 7 | version = "0.11.4" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" 10 | dependencies = [ 11 | "lazy_static", 12 | "regex", 13 | ] 14 | 15 | [[package]] 16 | name = "addr2line" 17 | version = "0.21.0" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 20 | dependencies = [ 21 | "gimli", 22 | ] 23 | 24 | [[package]] 25 | name = "adler" 26 | version = "1.0.2" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 29 | 30 | [[package]] 31 | name = "aho-corasick" 32 | version = "1.1.3" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 35 | dependencies = [ 36 | "memchr", 37 | ] 38 | 39 | [[package]] 40 | name = "async-graphql" 41 | version = "7.0.3" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "261fa27d5bff5afdf7beff291b3bc73f99d1529804c70e51b0fbc51e70b1c6a9" 44 | dependencies = [ 45 | "async-graphql-derive", 46 | "async-graphql-parser", 47 | "async-graphql-value", 48 | "async-stream", 49 | "async-trait", 50 | "base64", 51 | "bytes", 52 | "fnv", 53 | "futures-util", 54 | "handlebars", 55 | "http", 56 | "indexmap", 57 | "mime", 58 | "multer", 59 | "num-traits", 60 | "once_cell", 61 | "pin-project-lite", 62 | "regex", 63 | "serde", 64 | "serde_json", 65 | "serde_urlencoded", 66 | "static_assertions_next", 67 | "thiserror", 68 | ] 69 | 70 | [[package]] 71 | name = "async-graphql-axum" 72 | version = "7.0.3" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "93605d26b9da33b4cf6541906a9eb9e74396f1accbbc0f066e06f3b0869b84fc" 75 | dependencies = [ 76 | "async-graphql", 77 | "async-trait", 78 | "axum", 79 | "bytes", 80 | "futures-util", 81 | "serde_json", 82 | "tokio", 83 | "tokio-stream", 84 | "tokio-util", 85 | "tower-service", 86 | ] 87 | 88 | [[package]] 89 | name = "async-graphql-derive" 90 | version = "7.0.3" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "3188809947798ea6db736715a60cf645ba3b87ea031c710130e1476b48e45967" 93 | dependencies = [ 94 | "Inflector", 95 | "async-graphql-parser", 96 | "darling", 97 | "proc-macro-crate", 98 | "proc-macro2", 99 | "quote", 100 | "strum", 101 | "syn", 102 | "thiserror", 103 | ] 104 | 105 | [[package]] 106 | name = "async-graphql-parser" 107 | version = "7.0.3" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "d4e65a0b83027f35b2a5d9728a098bc66ac394caa8191d2c65ed9eb2985cf3d8" 110 | dependencies = [ 111 | "async-graphql-value", 112 | "pest", 113 | "serde", 114 | "serde_json", 115 | ] 116 | 117 | [[package]] 118 | name = "async-graphql-value" 119 | version = "7.0.3" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "68e40849c29a39012d38bff87bfed431f1ed6c53fbec493294c1045d61a7ae75" 122 | dependencies = [ 123 | "bytes", 124 | "indexmap", 125 | "serde", 126 | "serde_json", 127 | ] 128 | 129 | [[package]] 130 | name = "async-stream" 131 | version = "0.3.5" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" 134 | dependencies = [ 135 | "async-stream-impl", 136 | "futures-core", 137 | "pin-project-lite", 138 | ] 139 | 140 | [[package]] 141 | name = "async-stream-impl" 142 | version = "0.3.5" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" 145 | dependencies = [ 146 | "proc-macro2", 147 | "quote", 148 | "syn", 149 | ] 150 | 151 | [[package]] 152 | name = "async-trait" 153 | version = "0.1.80" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" 156 | dependencies = [ 157 | "proc-macro2", 158 | "quote", 159 | "syn", 160 | ] 161 | 162 | [[package]] 163 | name = "autocfg" 164 | version = "1.3.0" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 167 | 168 | [[package]] 169 | name = "axum" 170 | version = "0.7.5" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" 173 | dependencies = [ 174 | "async-trait", 175 | "axum-core", 176 | "base64", 177 | "bytes", 178 | "futures-util", 179 | "http", 180 | "http-body", 181 | "http-body-util", 182 | "hyper", 183 | "hyper-util", 184 | "itoa", 185 | "matchit", 186 | "memchr", 187 | "mime", 188 | "percent-encoding", 189 | "pin-project-lite", 190 | "rustversion", 191 | "serde", 192 | "serde_json", 193 | "serde_path_to_error", 194 | "serde_urlencoded", 195 | "sha1", 196 | "sync_wrapper 1.0.1", 197 | "tokio", 198 | "tokio-tungstenite", 199 | "tower", 200 | "tower-layer", 201 | "tower-service", 202 | "tracing", 203 | ] 204 | 205 | [[package]] 206 | name = "axum-core" 207 | version = "0.4.3" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" 210 | dependencies = [ 211 | "async-trait", 212 | "bytes", 213 | "futures-util", 214 | "http", 215 | "http-body", 216 | "http-body-util", 217 | "mime", 218 | "pin-project-lite", 219 | "rustversion", 220 | "sync_wrapper 0.1.2", 221 | "tower-layer", 222 | "tower-service", 223 | "tracing", 224 | ] 225 | 226 | [[package]] 227 | name = "backtrace" 228 | version = "0.3.71" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" 231 | dependencies = [ 232 | "addr2line", 233 | "cc", 234 | "cfg-if", 235 | "libc", 236 | "miniz_oxide", 237 | "object", 238 | "rustc-demangle", 239 | ] 240 | 241 | [[package]] 242 | name = "base64" 243 | version = "0.21.7" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 246 | 247 | [[package]] 248 | name = "block-buffer" 249 | version = "0.10.4" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 252 | dependencies = [ 253 | "generic-array", 254 | ] 255 | 256 | [[package]] 257 | name = "byteorder" 258 | version = "1.5.0" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 261 | 262 | [[package]] 263 | name = "bytes" 264 | version = "1.6.0" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 267 | dependencies = [ 268 | "serde", 269 | ] 270 | 271 | [[package]] 272 | name = "cc" 273 | version = "1.0.97" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" 276 | 277 | [[package]] 278 | name = "cfg-if" 279 | version = "1.0.0" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 282 | 283 | [[package]] 284 | name = "cpufeatures" 285 | version = "0.2.12" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 288 | dependencies = [ 289 | "libc", 290 | ] 291 | 292 | [[package]] 293 | name = "crypto-common" 294 | version = "0.1.6" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 297 | dependencies = [ 298 | "generic-array", 299 | "typenum", 300 | ] 301 | 302 | [[package]] 303 | name = "darling" 304 | version = "0.20.8" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" 307 | dependencies = [ 308 | "darling_core", 309 | "darling_macro", 310 | ] 311 | 312 | [[package]] 313 | name = "darling_core" 314 | version = "0.20.8" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" 317 | dependencies = [ 318 | "fnv", 319 | "ident_case", 320 | "proc-macro2", 321 | "quote", 322 | "strsim", 323 | "syn", 324 | ] 325 | 326 | [[package]] 327 | name = "darling_macro" 328 | version = "0.20.8" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" 331 | dependencies = [ 332 | "darling_core", 333 | "quote", 334 | "syn", 335 | ] 336 | 337 | [[package]] 338 | name = "data-encoding" 339 | version = "2.6.0" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" 342 | 343 | [[package]] 344 | name = "deunicode" 345 | version = "1.4.4" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" 348 | 349 | [[package]] 350 | name = "digest" 351 | version = "0.10.7" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 354 | dependencies = [ 355 | "block-buffer", 356 | "crypto-common", 357 | ] 358 | 359 | [[package]] 360 | name = "encoding_rs" 361 | version = "0.8.34" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" 364 | dependencies = [ 365 | "cfg-if", 366 | ] 367 | 368 | [[package]] 369 | name = "equivalent" 370 | version = "1.0.1" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 373 | 374 | [[package]] 375 | name = "fake" 376 | version = "2.9.2" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "1c25829bde82205da46e1823b2259db6273379f626fc211f126f65654a2669be" 379 | dependencies = [ 380 | "deunicode", 381 | "rand", 382 | ] 383 | 384 | [[package]] 385 | name = "fnv" 386 | version = "1.0.7" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 389 | 390 | [[package]] 391 | name = "form_urlencoded" 392 | version = "1.2.1" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 395 | dependencies = [ 396 | "percent-encoding", 397 | ] 398 | 399 | [[package]] 400 | name = "futures-channel" 401 | version = "0.3.30" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 404 | dependencies = [ 405 | "futures-core", 406 | ] 407 | 408 | [[package]] 409 | name = "futures-core" 410 | version = "0.3.30" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 413 | 414 | [[package]] 415 | name = "futures-io" 416 | version = "0.3.30" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 419 | 420 | [[package]] 421 | name = "futures-macro" 422 | version = "0.3.30" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 425 | dependencies = [ 426 | "proc-macro2", 427 | "quote", 428 | "syn", 429 | ] 430 | 431 | [[package]] 432 | name = "futures-sink" 433 | version = "0.3.30" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 436 | 437 | [[package]] 438 | name = "futures-task" 439 | version = "0.3.30" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 442 | 443 | [[package]] 444 | name = "futures-util" 445 | version = "0.3.30" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 448 | dependencies = [ 449 | "futures-core", 450 | "futures-io", 451 | "futures-macro", 452 | "futures-sink", 453 | "futures-task", 454 | "memchr", 455 | "pin-project-lite", 456 | "pin-utils", 457 | "slab", 458 | ] 459 | 460 | [[package]] 461 | name = "generic-array" 462 | version = "0.14.7" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 465 | dependencies = [ 466 | "typenum", 467 | "version_check", 468 | ] 469 | 470 | [[package]] 471 | name = "getrandom" 472 | version = "0.2.15" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 475 | dependencies = [ 476 | "cfg-if", 477 | "libc", 478 | "wasi", 479 | ] 480 | 481 | [[package]] 482 | name = "gimli" 483 | version = "0.28.1" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 486 | 487 | [[package]] 488 | name = "handlebars" 489 | version = "4.5.0" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" 492 | dependencies = [ 493 | "log", 494 | "pest", 495 | "pest_derive", 496 | "serde", 497 | "serde_json", 498 | "thiserror", 499 | ] 500 | 501 | [[package]] 502 | name = "hashbrown" 503 | version = "0.14.5" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 506 | 507 | [[package]] 508 | name = "heck" 509 | version = "0.4.1" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 512 | 513 | [[package]] 514 | name = "hermit-abi" 515 | version = "0.3.9" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 518 | 519 | [[package]] 520 | name = "http" 521 | version = "1.1.0" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 524 | dependencies = [ 525 | "bytes", 526 | "fnv", 527 | "itoa", 528 | ] 529 | 530 | [[package]] 531 | name = "http-body" 532 | version = "1.0.0" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" 535 | dependencies = [ 536 | "bytes", 537 | "http", 538 | ] 539 | 540 | [[package]] 541 | name = "http-body-util" 542 | version = "0.1.1" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" 545 | dependencies = [ 546 | "bytes", 547 | "futures-core", 548 | "http", 549 | "http-body", 550 | "pin-project-lite", 551 | ] 552 | 553 | [[package]] 554 | name = "httparse" 555 | version = "1.8.0" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 558 | 559 | [[package]] 560 | name = "httpdate" 561 | version = "1.0.3" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 564 | 565 | [[package]] 566 | name = "hyper" 567 | version = "1.3.1" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" 570 | dependencies = [ 571 | "bytes", 572 | "futures-channel", 573 | "futures-util", 574 | "http", 575 | "http-body", 576 | "httparse", 577 | "httpdate", 578 | "itoa", 579 | "pin-project-lite", 580 | "smallvec", 581 | "tokio", 582 | ] 583 | 584 | [[package]] 585 | name = "hyper-util" 586 | version = "0.1.3" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" 589 | dependencies = [ 590 | "bytes", 591 | "futures-util", 592 | "http", 593 | "http-body", 594 | "hyper", 595 | "pin-project-lite", 596 | "socket2", 597 | "tokio", 598 | ] 599 | 600 | [[package]] 601 | name = "ident_case" 602 | version = "1.0.1" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 605 | 606 | [[package]] 607 | name = "idna" 608 | version = "0.5.0" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 611 | dependencies = [ 612 | "unicode-bidi", 613 | "unicode-normalization", 614 | ] 615 | 616 | [[package]] 617 | name = "indexmap" 618 | version = "2.2.6" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 621 | dependencies = [ 622 | "equivalent", 623 | "hashbrown", 624 | "serde", 625 | ] 626 | 627 | [[package]] 628 | name = "itoa" 629 | version = "1.0.11" 630 | source = "registry+https://github.com/rust-lang/crates.io-index" 631 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 632 | 633 | [[package]] 634 | name = "lazy_static" 635 | version = "1.4.0" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 638 | 639 | [[package]] 640 | name = "libc" 641 | version = "0.2.154" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" 644 | 645 | [[package]] 646 | name = "log" 647 | version = "0.4.21" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 650 | 651 | [[package]] 652 | name = "matchit" 653 | version = "0.7.3" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" 656 | 657 | [[package]] 658 | name = "md5" 659 | version = "0.7.0" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" 662 | 663 | [[package]] 664 | name = "memchr" 665 | version = "2.7.2" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 668 | 669 | [[package]] 670 | name = "mime" 671 | version = "0.3.17" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 674 | 675 | [[package]] 676 | name = "miniz_oxide" 677 | version = "0.7.2" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 680 | dependencies = [ 681 | "adler", 682 | ] 683 | 684 | [[package]] 685 | name = "mio" 686 | version = "0.8.11" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 689 | dependencies = [ 690 | "libc", 691 | "wasi", 692 | "windows-sys 0.48.0", 693 | ] 694 | 695 | [[package]] 696 | name = "multer" 697 | version = "3.1.0" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" 700 | dependencies = [ 701 | "bytes", 702 | "encoding_rs", 703 | "futures-util", 704 | "http", 705 | "httparse", 706 | "memchr", 707 | "mime", 708 | "spin", 709 | "version_check", 710 | ] 711 | 712 | [[package]] 713 | name = "num-traits" 714 | version = "0.2.19" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 717 | dependencies = [ 718 | "autocfg", 719 | ] 720 | 721 | [[package]] 722 | name = "num_cpus" 723 | version = "1.16.0" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 726 | dependencies = [ 727 | "hermit-abi", 728 | "libc", 729 | ] 730 | 731 | [[package]] 732 | name = "object" 733 | version = "0.32.2" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 736 | dependencies = [ 737 | "memchr", 738 | ] 739 | 740 | [[package]] 741 | name = "once_cell" 742 | version = "1.19.0" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 745 | 746 | [[package]] 747 | name = "percent-encoding" 748 | version = "2.3.1" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 751 | 752 | [[package]] 753 | name = "pest" 754 | version = "2.7.10" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" 757 | dependencies = [ 758 | "memchr", 759 | "thiserror", 760 | "ucd-trie", 761 | ] 762 | 763 | [[package]] 764 | name = "pest_derive" 765 | version = "2.7.10" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" 768 | dependencies = [ 769 | "pest", 770 | "pest_generator", 771 | ] 772 | 773 | [[package]] 774 | name = "pest_generator" 775 | version = "2.7.10" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" 778 | dependencies = [ 779 | "pest", 780 | "pest_meta", 781 | "proc-macro2", 782 | "quote", 783 | "syn", 784 | ] 785 | 786 | [[package]] 787 | name = "pest_meta" 788 | version = "2.7.10" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" 791 | dependencies = [ 792 | "once_cell", 793 | "pest", 794 | "sha2", 795 | ] 796 | 797 | [[package]] 798 | name = "pin-project" 799 | version = "1.1.5" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" 802 | dependencies = [ 803 | "pin-project-internal", 804 | ] 805 | 806 | [[package]] 807 | name = "pin-project-internal" 808 | version = "1.1.5" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" 811 | dependencies = [ 812 | "proc-macro2", 813 | "quote", 814 | "syn", 815 | ] 816 | 817 | [[package]] 818 | name = "pin-project-lite" 819 | version = "0.2.14" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 822 | 823 | [[package]] 824 | name = "pin-utils" 825 | version = "0.1.0" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 828 | 829 | [[package]] 830 | name = "ppv-lite86" 831 | version = "0.2.17" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 834 | 835 | [[package]] 836 | name = "proc-macro-crate" 837 | version = "1.3.1" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 840 | dependencies = [ 841 | "once_cell", 842 | "toml_edit", 843 | ] 844 | 845 | [[package]] 846 | name = "proc-macro2" 847 | version = "1.0.81" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" 850 | dependencies = [ 851 | "unicode-ident", 852 | ] 853 | 854 | [[package]] 855 | name = "quote" 856 | version = "1.0.36" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 859 | dependencies = [ 860 | "proc-macro2", 861 | ] 862 | 863 | [[package]] 864 | name = "rand" 865 | version = "0.8.5" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 868 | dependencies = [ 869 | "libc", 870 | "rand_chacha", 871 | "rand_core", 872 | ] 873 | 874 | [[package]] 875 | name = "rand_chacha" 876 | version = "0.3.1" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 879 | dependencies = [ 880 | "ppv-lite86", 881 | "rand_core", 882 | ] 883 | 884 | [[package]] 885 | name = "rand_core" 886 | version = "0.6.4" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 889 | dependencies = [ 890 | "getrandom", 891 | ] 892 | 893 | [[package]] 894 | name = "regex" 895 | version = "1.10.4" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" 898 | dependencies = [ 899 | "aho-corasick", 900 | "memchr", 901 | "regex-automata", 902 | "regex-syntax", 903 | ] 904 | 905 | [[package]] 906 | name = "regex-automata" 907 | version = "0.4.6" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" 910 | dependencies = [ 911 | "aho-corasick", 912 | "memchr", 913 | "regex-syntax", 914 | ] 915 | 916 | [[package]] 917 | name = "regex-syntax" 918 | version = "0.8.3" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" 921 | 922 | [[package]] 923 | name = "rust-gql" 924 | version = "0.1.0" 925 | dependencies = [ 926 | "async-graphql", 927 | "async-graphql-axum", 928 | "axum", 929 | "fake", 930 | "md5", 931 | "rand", 932 | "tokio", 933 | "uuid", 934 | ] 935 | 936 | [[package]] 937 | name = "rustc-demangle" 938 | version = "0.1.23" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 941 | 942 | [[package]] 943 | name = "rustversion" 944 | version = "1.0.15" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" 947 | 948 | [[package]] 949 | name = "ryu" 950 | version = "1.0.17" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 953 | 954 | [[package]] 955 | name = "serde" 956 | version = "1.0.200" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" 959 | dependencies = [ 960 | "serde_derive", 961 | ] 962 | 963 | [[package]] 964 | name = "serde_derive" 965 | version = "1.0.200" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" 968 | dependencies = [ 969 | "proc-macro2", 970 | "quote", 971 | "syn", 972 | ] 973 | 974 | [[package]] 975 | name = "serde_json" 976 | version = "1.0.116" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" 979 | dependencies = [ 980 | "itoa", 981 | "ryu", 982 | "serde", 983 | ] 984 | 985 | [[package]] 986 | name = "serde_path_to_error" 987 | version = "0.1.16" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" 990 | dependencies = [ 991 | "itoa", 992 | "serde", 993 | ] 994 | 995 | [[package]] 996 | name = "serde_urlencoded" 997 | version = "0.7.1" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1000 | dependencies = [ 1001 | "form_urlencoded", 1002 | "itoa", 1003 | "ryu", 1004 | "serde", 1005 | ] 1006 | 1007 | [[package]] 1008 | name = "sha1" 1009 | version = "0.10.6" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1012 | dependencies = [ 1013 | "cfg-if", 1014 | "cpufeatures", 1015 | "digest", 1016 | ] 1017 | 1018 | [[package]] 1019 | name = "sha2" 1020 | version = "0.10.8" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1023 | dependencies = [ 1024 | "cfg-if", 1025 | "cpufeatures", 1026 | "digest", 1027 | ] 1028 | 1029 | [[package]] 1030 | name = "slab" 1031 | version = "0.4.9" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1034 | dependencies = [ 1035 | "autocfg", 1036 | ] 1037 | 1038 | [[package]] 1039 | name = "smallvec" 1040 | version = "1.13.2" 1041 | source = "registry+https://github.com/rust-lang/crates.io-index" 1042 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1043 | 1044 | [[package]] 1045 | name = "socket2" 1046 | version = "0.5.7" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 1049 | dependencies = [ 1050 | "libc", 1051 | "windows-sys 0.52.0", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "spin" 1056 | version = "0.9.8" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1059 | 1060 | [[package]] 1061 | name = "static_assertions_next" 1062 | version = "1.1.2" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766" 1065 | 1066 | [[package]] 1067 | name = "strsim" 1068 | version = "0.10.0" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1071 | 1072 | [[package]] 1073 | name = "strum" 1074 | version = "0.26.2" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" 1077 | dependencies = [ 1078 | "strum_macros", 1079 | ] 1080 | 1081 | [[package]] 1082 | name = "strum_macros" 1083 | version = "0.26.2" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" 1086 | dependencies = [ 1087 | "heck", 1088 | "proc-macro2", 1089 | "quote", 1090 | "rustversion", 1091 | "syn", 1092 | ] 1093 | 1094 | [[package]] 1095 | name = "syn" 1096 | version = "2.0.60" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" 1099 | dependencies = [ 1100 | "proc-macro2", 1101 | "quote", 1102 | "unicode-ident", 1103 | ] 1104 | 1105 | [[package]] 1106 | name = "sync_wrapper" 1107 | version = "0.1.2" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 1110 | 1111 | [[package]] 1112 | name = "sync_wrapper" 1113 | version = "1.0.1" 1114 | source = "registry+https://github.com/rust-lang/crates.io-index" 1115 | checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" 1116 | 1117 | [[package]] 1118 | name = "thiserror" 1119 | version = "1.0.59" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" 1122 | dependencies = [ 1123 | "thiserror-impl", 1124 | ] 1125 | 1126 | [[package]] 1127 | name = "thiserror-impl" 1128 | version = "1.0.59" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" 1131 | dependencies = [ 1132 | "proc-macro2", 1133 | "quote", 1134 | "syn", 1135 | ] 1136 | 1137 | [[package]] 1138 | name = "tinyvec" 1139 | version = "1.6.0" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1142 | dependencies = [ 1143 | "tinyvec_macros", 1144 | ] 1145 | 1146 | [[package]] 1147 | name = "tinyvec_macros" 1148 | version = "0.1.1" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1151 | 1152 | [[package]] 1153 | name = "tokio" 1154 | version = "1.37.0" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" 1157 | dependencies = [ 1158 | "backtrace", 1159 | "bytes", 1160 | "libc", 1161 | "mio", 1162 | "num_cpus", 1163 | "pin-project-lite", 1164 | "socket2", 1165 | "tokio-macros", 1166 | "windows-sys 0.48.0", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "tokio-macros" 1171 | version = "2.2.0" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" 1174 | dependencies = [ 1175 | "proc-macro2", 1176 | "quote", 1177 | "syn", 1178 | ] 1179 | 1180 | [[package]] 1181 | name = "tokio-stream" 1182 | version = "0.1.15" 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" 1184 | checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" 1185 | dependencies = [ 1186 | "futures-core", 1187 | "pin-project-lite", 1188 | "tokio", 1189 | ] 1190 | 1191 | [[package]] 1192 | name = "tokio-tungstenite" 1193 | version = "0.21.0" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" 1196 | dependencies = [ 1197 | "futures-util", 1198 | "log", 1199 | "tokio", 1200 | "tungstenite", 1201 | ] 1202 | 1203 | [[package]] 1204 | name = "tokio-util" 1205 | version = "0.7.11" 1206 | source = "registry+https://github.com/rust-lang/crates.io-index" 1207 | checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" 1208 | dependencies = [ 1209 | "bytes", 1210 | "futures-core", 1211 | "futures-io", 1212 | "futures-sink", 1213 | "pin-project-lite", 1214 | "tokio", 1215 | ] 1216 | 1217 | [[package]] 1218 | name = "toml_datetime" 1219 | version = "0.6.5" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" 1222 | 1223 | [[package]] 1224 | name = "toml_edit" 1225 | version = "0.19.15" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" 1228 | dependencies = [ 1229 | "indexmap", 1230 | "toml_datetime", 1231 | "winnow", 1232 | ] 1233 | 1234 | [[package]] 1235 | name = "tower" 1236 | version = "0.4.13" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 1239 | dependencies = [ 1240 | "futures-core", 1241 | "futures-util", 1242 | "pin-project", 1243 | "pin-project-lite", 1244 | "tokio", 1245 | "tower-layer", 1246 | "tower-service", 1247 | "tracing", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "tower-layer" 1252 | version = "0.3.2" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" 1255 | 1256 | [[package]] 1257 | name = "tower-service" 1258 | version = "0.3.2" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1261 | 1262 | [[package]] 1263 | name = "tracing" 1264 | version = "0.1.40" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1267 | dependencies = [ 1268 | "log", 1269 | "pin-project-lite", 1270 | "tracing-core", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "tracing-core" 1275 | version = "0.1.32" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1278 | dependencies = [ 1279 | "once_cell", 1280 | ] 1281 | 1282 | [[package]] 1283 | name = "tungstenite" 1284 | version = "0.21.0" 1285 | source = "registry+https://github.com/rust-lang/crates.io-index" 1286 | checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" 1287 | dependencies = [ 1288 | "byteorder", 1289 | "bytes", 1290 | "data-encoding", 1291 | "http", 1292 | "httparse", 1293 | "log", 1294 | "rand", 1295 | "sha1", 1296 | "thiserror", 1297 | "url", 1298 | "utf-8", 1299 | ] 1300 | 1301 | [[package]] 1302 | name = "typenum" 1303 | version = "1.17.0" 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" 1305 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1306 | 1307 | [[package]] 1308 | name = "ucd-trie" 1309 | version = "0.1.6" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" 1312 | 1313 | [[package]] 1314 | name = "unicode-bidi" 1315 | version = "0.3.15" 1316 | source = "registry+https://github.com/rust-lang/crates.io-index" 1317 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 1318 | 1319 | [[package]] 1320 | name = "unicode-ident" 1321 | version = "1.0.12" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1324 | 1325 | [[package]] 1326 | name = "unicode-normalization" 1327 | version = "0.1.23" 1328 | source = "registry+https://github.com/rust-lang/crates.io-index" 1329 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 1330 | dependencies = [ 1331 | "tinyvec", 1332 | ] 1333 | 1334 | [[package]] 1335 | name = "url" 1336 | version = "2.5.0" 1337 | source = "registry+https://github.com/rust-lang/crates.io-index" 1338 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" 1339 | dependencies = [ 1340 | "form_urlencoded", 1341 | "idna", 1342 | "percent-encoding", 1343 | ] 1344 | 1345 | [[package]] 1346 | name = "utf-8" 1347 | version = "0.7.6" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 1350 | 1351 | [[package]] 1352 | name = "uuid" 1353 | version = "1.8.0" 1354 | source = "registry+https://github.com/rust-lang/crates.io-index" 1355 | checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" 1356 | dependencies = [ 1357 | "getrandom", 1358 | ] 1359 | 1360 | [[package]] 1361 | name = "version_check" 1362 | version = "0.9.4" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1365 | 1366 | [[package]] 1367 | name = "wasi" 1368 | version = "0.11.0+wasi-snapshot-preview1" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1371 | 1372 | [[package]] 1373 | name = "windows-sys" 1374 | version = "0.48.0" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1377 | dependencies = [ 1378 | "windows-targets 0.48.5", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "windows-sys" 1383 | version = "0.52.0" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1386 | dependencies = [ 1387 | "windows-targets 0.52.5", 1388 | ] 1389 | 1390 | [[package]] 1391 | name = "windows-targets" 1392 | version = "0.48.5" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1395 | dependencies = [ 1396 | "windows_aarch64_gnullvm 0.48.5", 1397 | "windows_aarch64_msvc 0.48.5", 1398 | "windows_i686_gnu 0.48.5", 1399 | "windows_i686_msvc 0.48.5", 1400 | "windows_x86_64_gnu 0.48.5", 1401 | "windows_x86_64_gnullvm 0.48.5", 1402 | "windows_x86_64_msvc 0.48.5", 1403 | ] 1404 | 1405 | [[package]] 1406 | name = "windows-targets" 1407 | version = "0.52.5" 1408 | source = "registry+https://github.com/rust-lang/crates.io-index" 1409 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 1410 | dependencies = [ 1411 | "windows_aarch64_gnullvm 0.52.5", 1412 | "windows_aarch64_msvc 0.52.5", 1413 | "windows_i686_gnu 0.52.5", 1414 | "windows_i686_gnullvm", 1415 | "windows_i686_msvc 0.52.5", 1416 | "windows_x86_64_gnu 0.52.5", 1417 | "windows_x86_64_gnullvm 0.52.5", 1418 | "windows_x86_64_msvc 0.52.5", 1419 | ] 1420 | 1421 | [[package]] 1422 | name = "windows_aarch64_gnullvm" 1423 | version = "0.48.5" 1424 | source = "registry+https://github.com/rust-lang/crates.io-index" 1425 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1426 | 1427 | [[package]] 1428 | name = "windows_aarch64_gnullvm" 1429 | version = "0.52.5" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 1432 | 1433 | [[package]] 1434 | name = "windows_aarch64_msvc" 1435 | version = "0.48.5" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1438 | 1439 | [[package]] 1440 | name = "windows_aarch64_msvc" 1441 | version = "0.52.5" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 1444 | 1445 | [[package]] 1446 | name = "windows_i686_gnu" 1447 | version = "0.48.5" 1448 | source = "registry+https://github.com/rust-lang/crates.io-index" 1449 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1450 | 1451 | [[package]] 1452 | name = "windows_i686_gnu" 1453 | version = "0.52.5" 1454 | source = "registry+https://github.com/rust-lang/crates.io-index" 1455 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 1456 | 1457 | [[package]] 1458 | name = "windows_i686_gnullvm" 1459 | version = "0.52.5" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 1462 | 1463 | [[package]] 1464 | name = "windows_i686_msvc" 1465 | version = "0.48.5" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1468 | 1469 | [[package]] 1470 | name = "windows_i686_msvc" 1471 | version = "0.52.5" 1472 | source = "registry+https://github.com/rust-lang/crates.io-index" 1473 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 1474 | 1475 | [[package]] 1476 | name = "windows_x86_64_gnu" 1477 | version = "0.48.5" 1478 | source = "registry+https://github.com/rust-lang/crates.io-index" 1479 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1480 | 1481 | [[package]] 1482 | name = "windows_x86_64_gnu" 1483 | version = "0.52.5" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 1486 | 1487 | [[package]] 1488 | name = "windows_x86_64_gnullvm" 1489 | version = "0.48.5" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1492 | 1493 | [[package]] 1494 | name = "windows_x86_64_gnullvm" 1495 | version = "0.52.5" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 1498 | 1499 | [[package]] 1500 | name = "windows_x86_64_msvc" 1501 | version = "0.48.5" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1504 | 1505 | [[package]] 1506 | name = "windows_x86_64_msvc" 1507 | version = "0.52.5" 1508 | source = "registry+https://github.com/rust-lang/crates.io-index" 1509 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 1510 | 1511 | [[package]] 1512 | name = "winnow" 1513 | version = "0.5.40" 1514 | source = "registry+https://github.com/rust-lang/crates.io-index" 1515 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 1516 | dependencies = [ 1517 | "memchr", 1518 | ] 1519 | -------------------------------------------------------------------------------- /other-benchmarks/rust-gql/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-gql" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | axum = { version = "0.7.5", default-features = false } 10 | async-graphql = { version = "7.0.3", default-features = false, features = [ 11 | "graphiql", 12 | ] } 13 | async-graphql-axum = "7.0.3" 14 | md5 = "0.7.0" 15 | uuid = { version = "1.8.0", features = ["v4"] } 16 | fake = "2.9.2" 17 | rand = "0.8.5" 18 | tokio = { version = "1.37", features = ["macros", "rt-multi-thread"] } 19 | -------------------------------------------------------------------------------- /other-benchmarks/rust-gql/src/main.rs: -------------------------------------------------------------------------------- 1 | use axum::{ 2 | response::{self, IntoResponse}, 3 | routing::get, 4 | Router, 5 | }; 6 | 7 | use async_graphql::http::GraphiQLSource; 8 | use async_graphql_axum::GraphQL; 9 | 10 | use tokio::net::TcpListener; 11 | 12 | mod schema; 13 | 14 | async fn index_playground() -> impl IntoResponse { 15 | response::Html(GraphiQLSource::build().endpoint("/graphql").finish()) 16 | } 17 | 18 | #[tokio::main] 19 | async fn main() { 20 | let schema = schema::new_schema(); 21 | 22 | println!("Playground: http://localhost:4001/graphql"); 23 | 24 | let app = Router::new().route( 25 | "/graphql", 26 | get(index_playground).post_service(GraphQL::new(schema)), 27 | ); 28 | 29 | axum::serve(TcpListener::bind("127.0.0.1:4001").await.unwrap(), app) 30 | .await 31 | .unwrap(); 32 | } 33 | -------------------------------------------------------------------------------- /other-benchmarks/rust-gql/src/schema.rs: -------------------------------------------------------------------------------- 1 | use async_graphql::{ 2 | ComplexObject, EmptyMutation, EmptySubscription, Object, Schema, SimpleObject, ID, 3 | }; 4 | 5 | use fake::{self, Fake}; 6 | use rand::Rng; 7 | use uuid::Uuid; 8 | 9 | #[derive(SimpleObject)] 10 | pub struct Book { 11 | pub id: ID, 12 | pub name: String, 13 | pub num_pages: i32, 14 | } 15 | 16 | #[derive(SimpleObject)] 17 | #[graphql(complex)] 18 | pub struct Author { 19 | pub id: ID, 20 | pub name: String, 21 | pub company: String, 22 | 23 | #[graphql(skip)] 24 | books: Vec, 25 | } 26 | 27 | #[ComplexObject] 28 | impl Author { 29 | async fn md5(&self) -> String { 30 | format!("{:x}", md5::compute(self.name.as_bytes())) 31 | } 32 | 33 | async fn books(&self) -> &Vec { 34 | &self.books 35 | } 36 | } 37 | 38 | pub struct QueryRoot; 39 | 40 | #[Object] 41 | impl QueryRoot { 42 | async fn authors(&self) -> Vec { 43 | let mut authors: Vec = vec![]; 44 | 45 | for _i in 0..20 { 46 | let mut books: Vec = vec![]; 47 | 48 | for _i in 0..3 { 49 | books.push(Book { 50 | id: ID(Uuid::new_v4().to_string()), 51 | name: fake::faker::name::en::LastName().fake(), 52 | num_pages: rand::thread_rng().gen_range(100..10000), 53 | }); 54 | } 55 | 56 | authors.push(Author { 57 | id: ID(Uuid::new_v4().to_string()), 58 | name: fake::faker::name::en::FirstName().fake(), 59 | company: fake::faker::company::en::Bs().fake(), 60 | books, 61 | }); 62 | } 63 | 64 | authors 65 | } 66 | } 67 | 68 | pub type ServerSchema = Schema; 69 | 70 | pub fn new_schema() -> ServerSchema { 71 | Schema::new(QueryRoot, EmptyMutation, EmptySubscription) 72 | } 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fastify-benchmarks", 3 | "version": "1.0.0", 4 | "description": "Benchmarks for Fastify, a fast and low-overhead web framework.", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "cross-env NODE_ENV=production node benchmark.js && node benchmark.js compare -t", 8 | "bench": "node benchmark.js", 9 | "compare": "node benchmark.js compare --", 10 | "update-readme": "sed -n '1,21p' README.md > tmp.md && mv tmp.md README.md && node benchmark.js compare -tc >> README.md", 11 | "build": "tsc && mv dist/schemas/createTypeGraphQLSchema.js lib/schemas", 12 | "test": "standard | snazzy", 13 | "standard": "standard | snazzy", 14 | "eslint": "eslint . --ext .js --fix" 15 | }, 16 | "bin": { 17 | "benchmark": "./benchmark.js" 18 | }, 19 | "repository": "https://github.com/fastify/benchmarks.git", 20 | "author": "Çağatay Çalı", 21 | "contributors": [ 22 | "Ben Awad ", 23 | "/c² ", 24 | "Stefan Aichholzer ", 25 | "Matteo Collina ", 26 | "James Kyburz ", 27 | "Douglas Wilson ", 28 | "Hoang Vo ", 29 | "Jared Malcolm ", 30 | "Ardalan Amini ", 31 | "Peter Marton ", 32 | "Alex ", 33 | "Eran Hammer ", 34 | "Fabio Moretti ", 35 | "Jayden Seric ", 36 | "Jeff Wen ", 37 | "Lorenzo Sicilia ", 38 | "Luke Edwards ", 39 | "Martin Jesper Low Madsen ", 40 | "Your Name ", 41 | "Akos Kovacs ", 42 | "Evheniy ", 43 | "Fangdun Cai ", 44 | "Jerry Ng ", 45 | "Joshua Wise ", 46 | "Kristóf Poduszló ", 47 | "Matt Krick ", 48 | "MikluhaMaclay ", 49 | "Mohit Vachhani ", 50 | "Rzeszow ", 51 | "Tomas Della Vedova ", 52 | "Vitaly Domnikov ", 53 | "Zongmin Lei ", 54 | "dennistruemper ", 55 | "hnry ", 56 | "nichenqin ", 57 | "nodkz " 58 | ], 59 | "license": "MIT", 60 | "dependencies": { 61 | "@apollo/server": "^4.10.4", 62 | "@as-integrations/fastify": "^2.1.1", 63 | "@as-integrations/koa": "^1.1.1", 64 | "@benzene/http": "^0.4.2", 65 | "@benzene/jit": "^0.1.5", 66 | "@faker-js/faker": "^8.4.1", 67 | "@graphql-tools/schema": "^10.0.3", 68 | "@koa/cors": "^5.0.0", 69 | "@opentelemetry/exporter-trace-otlp-grpc": "^0.51.0", 70 | "@opentelemetry/instrumentation": "^0.51.0", 71 | "@opentelemetry/instrumentation-fastify": "^0.36.1", 72 | "@opentelemetry/instrumentation-graphql": "^0.40.0", 73 | "@opentelemetry/instrumentation-http": "^0.51.0", 74 | "@opentelemetry/resources": "^1.24.0", 75 | "@opentelemetry/sdk-trace-base": "^1.24.0", 76 | "@opentelemetry/sdk-trace-node": "^1.24.0", 77 | "@opentelemetry/semantic-conventions": "^1.24.0", 78 | "apollo-opentracing": "^3.0.45", 79 | "autocannon": "^7.15.0", 80 | "autocannon-compare": "^0.4.0", 81 | "body-parser": "^1.20.2", 82 | "chalk": "^4.1.2", 83 | "cli-table": "^0.3.11", 84 | "commander": "^12.0.0", 85 | "cors": "^2.8.5", 86 | "dd-trace": "^5.12.0", 87 | "express": "^4.19.2", 88 | "express-gql": "^0.0.11", 89 | "fast-json-stringify": "^5.15.1", 90 | "fastify": "^4.26.2", 91 | "graphql": "16.8.1", 92 | "graphql-api-koa": "^9.1.3", 93 | "graphql-compose": "^9.0.10", 94 | "graphql-http": "^1.22.1", 95 | "graphql-jit": "^0.8.6", 96 | "graphql-tag": "^2.12.6", 97 | "graphql-upload": "^15.0.2", 98 | "graphql-yoga": "^5.3.0", 99 | "inquirer": "^9.2.20", 100 | "koa": "^2.15.3", 101 | "koa-bodyparser": "^4.4.1", 102 | "md5": "^2.3.0", 103 | "mercurius": "^14.1.0", 104 | "ora": "^8.0.1", 105 | "reflect-metadata": "^0.2.2", 106 | "turbo-json-parse": "^2.3.0", 107 | "type-graphql": "^2.0.0-rc.1", 108 | "uWebSockets.js": "uNetworking/uWebSockets.js#v20.43.0" 109 | }, 110 | "devDependencies": { 111 | "@types/autocannon": "^7.12.5", 112 | "@types/cli-table": "^0.3.4", 113 | "@types/connect": "^3.4.38", 114 | "@types/cors": "^2.8.17", 115 | "@types/express": "^4.17.21", 116 | "@types/hapi__hapi": "^20.0.13", 117 | "@types/inquirer": "^9.0.7", 118 | "@types/koa": "^2.15.0", 119 | "@types/md5": "^2.3.5", 120 | "@types/micro": "^7.3.7", 121 | "@types/restify": "^8.5.12", 122 | "@typescript-eslint/eslint-plugin": "^7.8.0", 123 | "@typescript-eslint/parser": "^7.8.0", 124 | "cross-env": "^7.0.3", 125 | "eslint": "^8.2.0", 126 | "eslint-config-airbnb-base": "^15.0.0", 127 | "eslint-config-prettier": "^9.1.0", 128 | "eslint-plugin-import": "^2.29.1", 129 | "eslint-plugin-prettier": "^5.1.3", 130 | "prettier": "^3.2.5", 131 | "snazzy": "^9.0.0", 132 | "standard": "^17.1.0", 133 | "typescript": "^5.4.5" 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /run/application_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "session": { 4 | "maxAge": 86400000, 5 | "key": "EGG_SESS", 6 | "httpOnly": true, 7 | "encrypt": true, 8 | "overwrite": true, 9 | "signed": true, 10 | "autoCommit": true, 11 | "encode": "", 12 | "decode": "", 13 | "genid": "" 14 | }, 15 | "security": { 16 | "domainWhiteList": [], 17 | "protocolWhiteList": [], 18 | "defaultMiddleware": "csrf,hsts,methodnoallow,noopen,nosniff,csp,xssProtection,xframe,dta", 19 | "csrf": { 20 | "enable": true, 21 | "useSession": false, 22 | "ignoreJSON": false, 23 | "cookieName": "csrfToken", 24 | "sessionName": "csrfToken", 25 | "headerName": "x-csrf-token", 26 | "bodyName": "_csrf", 27 | "queryName": "_csrf", 28 | "matching": "" 29 | }, 30 | "xframe": { 31 | "enable": true, 32 | "value": "SAMEORIGIN", 33 | "matching": "" 34 | }, 35 | "hsts": { 36 | "enable": false, 37 | "maxAge": 31536000, 38 | "includeSubdomains": false 39 | }, 40 | "dta": { 41 | "enable": true, 42 | "matching": "" 43 | }, 44 | "methodnoallow": { 45 | "enable": true, 46 | "matching": "" 47 | }, 48 | "noopen": { 49 | "enable": true, 50 | "matching": "" 51 | }, 52 | "nosniff": { 53 | "enable": true, 54 | "matching": "" 55 | }, 56 | "referrerPolicy": { 57 | "enable": false, 58 | "value": "no-referrer-when-downgrade" 59 | }, 60 | "xssProtection": { 61 | "enable": true, 62 | "value": "1; mode=block", 63 | "matching": "" 64 | }, 65 | "csp": { 66 | "enable": false, 67 | "policy": {} 68 | }, 69 | "ssrf": { 70 | "ipBlackList": null, 71 | "checkAddress": null 72 | }, 73 | "_protocolWhiteListSet": "" 74 | }, 75 | "helper": { 76 | "shtml": {} 77 | }, 78 | "jsonp": { 79 | "limit": 50, 80 | "callback": [ 81 | "_callback", 82 | "callback" 83 | ], 84 | "csrf": false 85 | }, 86 | "onerror": { 87 | "errorPageUrl": "", 88 | "appErrorFilter": null, 89 | "templatePath": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-onerror/lib/onerror_page.mustache" 90 | }, 91 | "i18n": { 92 | "defaultLocale": "en_US", 93 | "dirs": [ 94 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-session/config/locales", 95 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/locales", 96 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-jsonp/config/locales", 97 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-onerror/config/locales", 98 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-i18n/config/locales", 99 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-watcher/config/locales", 100 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-schedule/config/locales", 101 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/locales", 102 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-development/config/locales", 103 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator/config/locales", 104 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-static/config/locales", 105 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-view/config/locales", 106 | "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/locales", 107 | "/Users/jameskyburz/Documents/src/benchmarks/config/locales" 108 | ], 109 | "queryField": "locale", 110 | "cookieField": "locale", 111 | "cookieMaxAge": "1y", 112 | "functionName": "__" 113 | }, 114 | "watcher": { 115 | "type": "development", 116 | "eventSources": { 117 | "default": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-watcher/lib/event-sources/default", 118 | "development": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-watcher/lib/event-sources/development" 119 | } 120 | }, 121 | "customLogger": { 122 | "scheduleLogger": { 123 | "consoleLevel": "NONE", 124 | "file": "/Users/jameskyburz/Documents/src/benchmarks/logs/fastify-benchmarks/egg-schedule.log" 125 | } 126 | }, 127 | "multipart": { 128 | "mode": "stream", 129 | "autoFields": false, 130 | "defaultCharset": "utf8", 131 | "fieldNameSize": 100, 132 | "fieldSize": 102400, 133 | "fields": 10, 134 | "fileSize": 10485760, 135 | "files": 10, 136 | "fileExtensions": [], 137 | "whitelist": null, 138 | "tmpdir": "/var/folders/8s/kdbw0knx3ks5n_nq5k9wlrqc0000gn/T/egg-multipart-tmp/fastify-benchmarks", 139 | "cleanSchedule": { 140 | "cron": "0 30 4 * * *" 141 | } 142 | }, 143 | "development": { 144 | "watchDirs": [], 145 | "ignoreDirs": [], 146 | "fastReady": false, 147 | "reloadOnDebug": true, 148 | "overrideDefault": false 149 | }, 150 | "logrotator": { 151 | "filesRotateByHour": null, 152 | "hourDelimiter": "-", 153 | "filesRotateBySize": null, 154 | "maxFileSize": 52428800, 155 | "maxFiles": 10, 156 | "rotateDuration": 60000, 157 | "maxDays": 31 158 | }, 159 | "static": { 160 | "prefix": "/public/", 161 | "dir": "/Users/jameskyburz/Documents/src/benchmarks/app/public", 162 | "dynamic": true, 163 | "preload": false, 164 | "buffer": false, 165 | "maxFiles": 1000, 166 | "files": "" 167 | }, 168 | "view": { 169 | "root": "/Users/jameskyburz/Documents/src/benchmarks/app/view", 170 | "cache": false, 171 | "defaultExtension": ".html", 172 | "defaultViewEngine": "", 173 | "mapping": {} 174 | }, 175 | "env": "local", 176 | "name": "fastify-benchmarks", 177 | "keys": "", 178 | "proxy": false, 179 | "protocolHeaders": "x-forwarded-proto", 180 | "ipHeaders": "x-forwarded-for", 181 | "hostHeaders": "", 182 | "pkg": { 183 | "name": "fastify-benchmarks", 184 | "version": "0.3.6", 185 | "description": "Benchmarks for Fastify, a fast and low-overhead web framework.", 186 | "main": "index.js", 187 | "scripts": { 188 | "start": "node benchmark.js", 189 | "compare": "node benchmark.js compare --", 190 | "test": "standard | snazzy", 191 | "standard": "standard | snazzy" 192 | }, 193 | "bin": { 194 | "benchmark": "./benchmark.js" 195 | }, 196 | "repository": "https://github.com/fastify/benchmarks.git", 197 | "author": "Çağatay Çalı", 198 | "license": "MIT", 199 | "dependencies": { 200 | "@leizm/web": "^2.5.1", 201 | "autocannon": "^3.2.0", 202 | "autocannon-compare": "^0.3.0", 203 | "chalk": "^2.4.1", 204 | "cli-table": "^0.3.1", 205 | "commander": "^2.15.1", 206 | "connect": "^3.6.6", 207 | "cors": "^2.8.5", 208 | "dns-prefetch-control": "^0.1.0", 209 | "egg": "^2.11.2", 210 | "express": "^4.16.3", 211 | "fastify": "^1.6.0", 212 | "foxify": "^0.10.6", 213 | "frameguard": "^3.0.0", 214 | "hapi": "^17.5.1", 215 | "hide-powered-by": "^1.0.0", 216 | "hsts": "^2.1.0", 217 | "ienoopen": "^1.0.0", 218 | "inquirer": "^6.0.0", 219 | "koa": "^2.5.1", 220 | "koa-router": "^7.4.0", 221 | "make-promises-safe": "^4.0.0", 222 | "micro": "^9.3.2", 223 | "micro-route": "^2.5.0", 224 | "microrouter": "^3.1.3", 225 | "ora": "^3.0.0", 226 | "polka": "^0.5.1", 227 | "rayo": "^1.0.4", 228 | "restify": "^7.2.1", 229 | "router": "^1.3.3", 230 | "server-base": "^6.0.0", 231 | "server-base-router": "^6.0.0", 232 | "spirit": "^0.6.1", 233 | "spirit-router": "^0.5.0", 234 | "take-five": "^2.0.0", 235 | "total.js": "^3.0.0", 236 | "trek-engine": "^1.0.5", 237 | "trek-router": "^1.2.0", 238 | "vapr": "^0.5.1", 239 | "x-xss-protection": "^1.1.0" 240 | }, 241 | "devDependencies": { 242 | "snazzy": "^8.0.0", 243 | "standard": "^12.0.1" 244 | } 245 | }, 246 | "baseDir": "/Users/jameskyburz/Documents/src/benchmarks", 247 | "HOME": "/Users/jameskyburz", 248 | "rundir": "/Users/jameskyburz/Documents/src/benchmarks/run", 249 | "dump": { 250 | "ignore": "" 251 | }, 252 | "confusedConfigurations": { 253 | "bodyparser": "bodyParser", 254 | "notFound": "notfound", 255 | "sitefile": "siteFile", 256 | "middlewares": "middleware", 257 | "httpClient": "httpclient" 258 | }, 259 | "notfound": { 260 | "pageUrl": "" 261 | }, 262 | "siteFile": { 263 | "/favicon.ico": "" 264 | }, 265 | "bodyParser": { 266 | "enable": true, 267 | "encoding": "utf8", 268 | "formLimit": "100kb", 269 | "jsonLimit": "100kb", 270 | "strict": true, 271 | "queryString": { 272 | "arrayLimit": 100, 273 | "depth": 5, 274 | "parameterLimit": 1000 275 | }, 276 | "returnRawBody": true 277 | }, 278 | "logger": { 279 | "dir": "/Users/jameskyburz/Documents/src/benchmarks/logs/fastify-benchmarks", 280 | "encoding": "utf8", 281 | "env": "local", 282 | "level": "INFO", 283 | "consoleLevel": "INFO", 284 | "disableConsoleAfterReady": false, 285 | "outputJSON": false, 286 | "buffer": true, 287 | "appLogName": "fastify-benchmarks-web.log", 288 | "coreLogName": "egg-web.log", 289 | "agentLogName": "egg-agent.log", 290 | "errorLogName": "common-error.log", 291 | "coreLogger": { 292 | "consoleLevel": "WARN" 293 | }, 294 | "allowDebugAtProd": false, 295 | "type": "application" 296 | }, 297 | "httpclient": { 298 | "enableDNSCache": false, 299 | "dnsCacheLookupInterval": 10000, 300 | "dnsCacheMaxLength": 1000, 301 | "request": { 302 | "timeout": 5000 303 | }, 304 | "httpAgent": { 305 | "keepAlive": true, 306 | "freeSocketTimeout": 4000, 307 | "maxSockets": 9007199254740991, 308 | "maxFreeSockets": 256 309 | }, 310 | "httpsAgent": { 311 | "keepAlive": true, 312 | "freeSocketTimeout": 4000, 313 | "maxSockets": 9007199254740991, 314 | "maxFreeSockets": 256 315 | } 316 | }, 317 | "meta": { 318 | "enable": true, 319 | "logging": false 320 | }, 321 | "coreMiddleware": [ 322 | "meta", 323 | "siteFile", 324 | "notfound", 325 | "static", 326 | "bodyParser", 327 | "overrideMethod", 328 | "session", 329 | "securities", 330 | "i18n", 331 | "eggLoaderTrace" 332 | ], 333 | "workerStartTimeout": 600000, 334 | "serverTimeout": null, 335 | "cluster": { 336 | "listen": { 337 | "path": "", 338 | "port": 7001, 339 | "hostname": "" 340 | } 341 | }, 342 | "clusterClient": { 343 | "maxWaitTime": 60000, 344 | "responseTimeout": 60000 345 | }, 346 | "onClientError": null, 347 | "coreMiddlewares": "~config~coreMiddleware", 348 | "appMiddlewares": [], 349 | "appMiddleware": "~config~appMiddlewares", 350 | "multipartParseOptions": { 351 | "autoFields": false, 352 | "defCharset": "utf8", 353 | "limits": { 354 | "fieldNameSize": 100, 355 | "fieldSize": 102400, 356 | "fields": 10, 357 | "fileSize": 10485760, 358 | "files": 10 359 | }, 360 | "checkFile": "" 361 | } 362 | }, 363 | "plugins": { 364 | "session": { 365 | "enable": true, 366 | "package": "egg-session", 367 | "name": "session", 368 | "dependencies": [], 369 | "optionalDependencies": [], 370 | "env": [], 371 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 372 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-session", 373 | "version": "3.1.0" 374 | }, 375 | "security": { 376 | "enable": true, 377 | "package": "egg-security", 378 | "name": "security", 379 | "dependencies": [], 380 | "optionalDependencies": [ 381 | "session" 382 | ], 383 | "env": [], 384 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 385 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security", 386 | "version": "2.4.1" 387 | }, 388 | "jsonp": { 389 | "enable": true, 390 | "package": "egg-jsonp", 391 | "name": "jsonp", 392 | "dependencies": [], 393 | "optionalDependencies": [ 394 | "security" 395 | ], 396 | "env": [], 397 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 398 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-jsonp", 399 | "version": "2.0.0" 400 | }, 401 | "onerror": { 402 | "enable": true, 403 | "package": "egg-onerror", 404 | "name": "onerror", 405 | "dependencies": [], 406 | "optionalDependencies": [ 407 | "jsonp" 408 | ], 409 | "env": [], 410 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 411 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-onerror", 412 | "version": "2.1.0" 413 | }, 414 | "i18n": { 415 | "enable": true, 416 | "package": "egg-i18n", 417 | "name": "i18n", 418 | "dependencies": [], 419 | "optionalDependencies": [], 420 | "env": [], 421 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 422 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-i18n", 423 | "version": "2.0.0" 424 | }, 425 | "watcher": { 426 | "enable": true, 427 | "package": "egg-watcher", 428 | "name": "watcher", 429 | "dependencies": [], 430 | "optionalDependencies": [], 431 | "env": [], 432 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 433 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-watcher", 434 | "version": "3.1.0" 435 | }, 436 | "schedule": { 437 | "enable": true, 438 | "package": "egg-schedule", 439 | "name": "schedule", 440 | "dependencies": [], 441 | "optionalDependencies": [], 442 | "env": [], 443 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 444 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-schedule", 445 | "version": "3.4.0" 446 | }, 447 | "multipart": { 448 | "enable": true, 449 | "package": "egg-multipart", 450 | "name": "multipart", 451 | "dependencies": [], 452 | "optionalDependencies": [ 453 | "schedule" 454 | ], 455 | "env": [], 456 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 457 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart", 458 | "version": "2.3.0" 459 | }, 460 | "development": { 461 | "enable": true, 462 | "package": "egg-development", 463 | "name": "development", 464 | "dependencies": [ 465 | "watcher" 466 | ], 467 | "optionalDependencies": [], 468 | "env": [ 469 | "local" 470 | ], 471 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 472 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-development", 473 | "version": "2.4.1" 474 | }, 475 | "logrotator": { 476 | "enable": true, 477 | "package": "egg-logrotator", 478 | "name": "logrotator", 479 | "dependencies": [ 480 | "schedule" 481 | ], 482 | "optionalDependencies": [], 483 | "env": [], 484 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 485 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator", 486 | "version": "3.0.4" 487 | }, 488 | "static": { 489 | "enable": true, 490 | "package": "egg-static", 491 | "name": "static", 492 | "dependencies": [], 493 | "optionalDependencies": [], 494 | "env": [], 495 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 496 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-static", 497 | "version": "2.1.1" 498 | }, 499 | "view": { 500 | "enable": true, 501 | "package": "egg-view", 502 | "name": "view", 503 | "dependencies": [], 504 | "optionalDependencies": [], 505 | "env": [], 506 | "from": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/plugin.js", 507 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-view", 508 | "version": "2.1.0" 509 | } 510 | } 511 | } -------------------------------------------------------------------------------- /run/application_config_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "session": { 3 | "maxAge": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-session/config/config.default.js", 4 | "key": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-session/config/config.default.js", 5 | "httpOnly": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-session/config/config.default.js", 6 | "encrypt": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-session/config/config.default.js" 7 | }, 8 | "security": { 9 | "domainWhiteList": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 10 | "protocolWhiteList": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 11 | "defaultMiddleware": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 12 | "csrf": { 13 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 14 | "useSession": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 15 | "ignoreJSON": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 16 | "cookieName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 17 | "sessionName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 18 | "headerName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 19 | "bodyName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 20 | "queryName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 21 | }, 22 | "xframe": { 23 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 24 | "value": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 25 | }, 26 | "hsts": { 27 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.local.js", 28 | "maxAge": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 29 | "includeSubdomains": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 30 | }, 31 | "dta": { 32 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 33 | }, 34 | "methodnoallow": { 35 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 36 | }, 37 | "noopen": { 38 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 39 | }, 40 | "nosniff": { 41 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 42 | }, 43 | "referrerPolicy": { 44 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 45 | "value": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 46 | }, 47 | "xssProtection": { 48 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 49 | "value": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 50 | }, 51 | "csp": { 52 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 53 | "policy": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 54 | }, 55 | "ssrf": { 56 | "ipBlackList": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js", 57 | "checkAddress": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 58 | } 59 | }, 60 | "helper": { 61 | "shtml": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-security/config/config.default.js" 62 | }, 63 | "jsonp": { 64 | "limit": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-jsonp/config/config.default.js", 65 | "callback": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-jsonp/config/config.default.js", 66 | "csrf": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-jsonp/config/config.default.js" 67 | }, 68 | "onerror": { 69 | "errorPageUrl": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-onerror/config/config.default.js", 70 | "appErrorFilter": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-onerror/config/config.default.js", 71 | "templatePath": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-onerror/config/config.default.js" 72 | }, 73 | "i18n": { 74 | "defaultLocale": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-i18n/config/config.default.js", 75 | "dirs": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-i18n/config/config.default.js", 76 | "queryField": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-i18n/config/config.default.js", 77 | "cookieField": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-i18n/config/config.default.js", 78 | "cookieMaxAge": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-i18n/config/config.default.js" 79 | }, 80 | "watcher": { 81 | "type": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-watcher/config/config.local.js", 82 | "eventSources": { 83 | "default": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-watcher/config/config.default.js", 84 | "development": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-watcher/config/config.default.js" 85 | } 86 | }, 87 | "customLogger": { 88 | "scheduleLogger": { 89 | "consoleLevel": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-schedule/config/config.default.js", 90 | "file": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-schedule/config/config.default.js" 91 | } 92 | }, 93 | "multipart": { 94 | "mode": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 95 | "autoFields": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 96 | "defaultCharset": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 97 | "fieldNameSize": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 98 | "fieldSize": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 99 | "fields": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 100 | "fileSize": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 101 | "files": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 102 | "fileExtensions": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 103 | "whitelist": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 104 | "tmpdir": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js", 105 | "cleanSchedule": { 106 | "cron": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-multipart/config/config.default.js" 107 | } 108 | }, 109 | "development": { 110 | "watchDirs": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-development/config/config.default.js", 111 | "ignoreDirs": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-development/config/config.default.js", 112 | "fastReady": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-development/config/config.default.js", 113 | "reloadOnDebug": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-development/config/config.default.js", 114 | "overrideDefault": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-development/config/config.default.js" 115 | }, 116 | "logrotator": { 117 | "filesRotateByHour": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator/config/config.default.js", 118 | "hourDelimiter": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator/config/config.default.js", 119 | "filesRotateBySize": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator/config/config.default.js", 120 | "maxFileSize": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator/config/config.default.js", 121 | "maxFiles": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator/config/config.default.js", 122 | "rotateDuration": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator/config/config.default.js", 123 | "maxDays": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-logrotator/config/config.default.js" 124 | }, 125 | "static": { 126 | "prefix": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-static/config/config.default.js", 127 | "dir": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-static/config/config.default.js", 128 | "dynamic": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-static/config/config.default.js", 129 | "preload": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-static/config/config.default.js", 130 | "buffer": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-static/config/config.default.js", 131 | "maxFiles": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-static/config/config.default.js" 132 | }, 133 | "view": { 134 | "root": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-view/config/config.default.js", 135 | "cache": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-view/config/config.local.js", 136 | "defaultExtension": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-view/config/config.default.js", 137 | "defaultViewEngine": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-view/config/config.default.js", 138 | "mapping": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg-view/config/config.default.js" 139 | }, 140 | "env": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 141 | "name": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 142 | "keys": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 143 | "proxy": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 144 | "protocolHeaders": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 145 | "ipHeaders": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 146 | "hostHeaders": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 147 | "pkg": { 148 | "name": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 149 | "version": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 150 | "description": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 151 | "main": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 152 | "scripts": { 153 | "start": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 154 | "compare": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 155 | "test": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 156 | "standard": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 157 | }, 158 | "bin": { 159 | "benchmark": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 160 | }, 161 | "repository": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 162 | "author": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 163 | "license": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 164 | "dependencies": { 165 | "@leizm/web": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 166 | "autocannon": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 167 | "autocannon-compare": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 168 | "chalk": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 169 | "cli-table": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 170 | "commander": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 171 | "connect": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 172 | "cors": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 173 | "dns-prefetch-control": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 174 | "egg": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 175 | "express": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 176 | "fastify": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 177 | "foxify": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 178 | "frameguard": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 179 | "hapi": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 180 | "hide-powered-by": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 181 | "hsts": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 182 | "ienoopen": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 183 | "inquirer": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 184 | "koa": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 185 | "koa-router": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 186 | "make-promises-safe": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 187 | "micro": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 188 | "micro-route": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 189 | "microrouter": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 190 | "ora": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 191 | "polka": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 192 | "rayo": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 193 | "restify": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 194 | "router": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 195 | "server-base": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 196 | "server-base-router": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 197 | "spirit": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 198 | "spirit-router": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 199 | "take-five": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 200 | "total.js": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 201 | "trek-engine": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 202 | "trek-router": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 203 | "vapr": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 204 | "x-xss-protection": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 205 | }, 206 | "devDependencies": { 207 | "snazzy": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 208 | "standard": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 209 | } 210 | }, 211 | "baseDir": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 212 | "HOME": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 213 | "rundir": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 214 | "dump": { 215 | "ignore": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 216 | }, 217 | "confusedConfigurations": { 218 | "bodyparser": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 219 | "notFound": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 220 | "sitefile": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 221 | "middlewares": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 222 | "httpClient": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 223 | }, 224 | "notfound": { 225 | "pageUrl": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 226 | }, 227 | "siteFile": { 228 | "/favicon.ico": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 229 | }, 230 | "bodyParser": { 231 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 232 | "encoding": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 233 | "formLimit": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 234 | "jsonLimit": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 235 | "strict": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 236 | "queryString": { 237 | "arrayLimit": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 238 | "depth": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 239 | "parameterLimit": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 240 | } 241 | }, 242 | "logger": { 243 | "dir": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 244 | "encoding": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 245 | "env": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 246 | "level": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 247 | "consoleLevel": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 248 | "disableConsoleAfterReady": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 249 | "outputJSON": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 250 | "buffer": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 251 | "appLogName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 252 | "coreLogName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 253 | "agentLogName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 254 | "errorLogName": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 255 | "coreLogger": { 256 | "consoleLevel": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.local.js" 257 | }, 258 | "allowDebugAtProd": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 259 | }, 260 | "httpclient": { 261 | "enableDNSCache": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 262 | "dnsCacheLookupInterval": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 263 | "dnsCacheMaxLength": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 264 | "request": { 265 | "timeout": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 266 | }, 267 | "httpAgent": { 268 | "keepAlive": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 269 | "freeSocketTimeout": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 270 | "maxSockets": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 271 | "maxFreeSockets": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 272 | }, 273 | "httpsAgent": { 274 | "keepAlive": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 275 | "freeSocketTimeout": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 276 | "maxSockets": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 277 | "maxFreeSockets": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 278 | } 279 | }, 280 | "meta": { 281 | "enable": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 282 | "logging": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 283 | }, 284 | "coreMiddleware": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 285 | "workerStartTimeout": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 286 | "serverTimeout": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 287 | "cluster": { 288 | "listen": { 289 | "path": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 290 | "port": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 291 | "hostname": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 292 | } 293 | }, 294 | "clusterClient": { 295 | "maxWaitTime": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js", 296 | "responseTimeout": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 297 | }, 298 | "onClientError": "/Users/jameskyburz/Documents/src/benchmarks/node_modules/egg/config/config.default.js" 299 | } -------------------------------------------------------------------------------- /run/router.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "lib": ["dom", "es6", "es2017", "esnext.asynciterable"], 6 | "sourceMap": true, 7 | "outDir": "./dist", 8 | "moduleResolution": "node", 9 | "removeComments": true, 10 | "skipLibCheck": true, 11 | "noImplicitAny": true, 12 | "strictNullChecks": true, 13 | "strictFunctionTypes": true, 14 | "allowJs": true, 15 | "noImplicitThis": true, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": true, 18 | "noImplicitReturns": true, 19 | "noFallthroughCasesInSwitch": true, 20 | "allowSyntheticDefaultImports": true, 21 | "esModuleInterop": true, 22 | "emitDecoratorMetadata": true, 23 | "experimentalDecorators": true, 24 | "resolveJsonModule": true, 25 | "baseUrl": "." 26 | }, 27 | "exclude": ["node_modules"], 28 | "include": ["./lib/**/createTypeGraphQLSchema.ts"] 29 | } 30 | --------------------------------------------------------------------------------