Giter Site home page Giter Site logo

hoangvvo / benzene Goto Github PK

View Code? Open in Web Editor NEW
163.0 163.0 6.0 1.85 MB

⌬ Fast, minimal, agnostic GraphQL Servers ⌬

Home Page: https://benzene.vercel.app

License: Other

TypeScript 94.71% JavaScript 4.51% Shell 0.44% Lua 0.33%
cloudflare-workers deno graphql graphql-server javascript node websocket

benzene's People

Contributors

adamjnavarro avatar github-actions[bot] avatar hoangvvo avatar rfgamaral avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

benzene's Issues

Hyper-Express + Benzene benchmark

Just tried out what is in the title, gave the best result.

https://github.com/kartikk221/hyper-express

https://github.com/kartikk221/hyper-express/blob/master/docs/Benchmarks.md

Machine: Linux 5.15.25-xanmod1 x86_64 | 16 vCPUs | 32GB
Node: v16.13.0

apollo-server
  Slowest:	0.0564 secs
  Fastest:	0.0038 secs
  Average:	0.0192 secs
  Requests/sec:	5204.7523
  
benzene-http
  Slowest:	0.0230 secs
  Fastest:	0.0036 secs
  Average:	0.0070 secs
  Requests/sec:	14187.0487
  
benzene-jit-http
  Slowest:	0.0165 secs
  Fastest:	0.0032 secs
  Average:	0.0041 secs
  Requests/sec:	24527.6361
  
express-graphql
  Slowest:	0.0818 secs
  Fastest:	0.0039 secs
  Average:	0.0323 secs
  Requests/sec:	3092.1393
  
graphql-helix
  Slowest:	0.0779 secs
  Fastest:	0.0045 secs
  Average:	0.0316 secs
  Requests/sec:	3153.4511
  
hyper-express-benzene
  Slowest:	0.0128 secs
  Fastest:	0.0004 secs
  Average:	0.0036 secs
  Requests/sec:	27913.0988
  
mercurius
  Slowest:	0.0259 secs
  Fastest:	0.0029 secs
  Average:	0.0050 secs
  Requests/sec:	19885.1838

All with their latest version

  "dependencies": {
    "@benzene/http": "0.4.1",
    "@benzene/jit": "0.1.4",
    "apollo-server": "3.6.3",
    "express-graphql": "^0.12.0",
    "fastify": "3.27.2",
    "graphql-helix": "1.11.0",
    "hyper-express": "5.8.2",
    "mercurius": "9.3.3"
  }

I might not open a PR, but if someone wants, here is what I did.

const { Benzene, makeHandler, parseGraphQLBody } = require("@benzene/http");
const { makeCompileQuery } = require("@benzene/jit");
const HyperExpress = require("hyper-express");
const schema = require("../schema");

const server = new HyperExpress.Server();

const GQL = new Benzene({ schema, compileQuery: makeCompileQuery() });

const graphqlHTTP = makeHandler(GQL);

server.post("/graphql", async (request, response) => {
  const body = await request.json();
  graphqlHTTP({
    method: request.method,
    headers: request.headers,
    body,
  }).then((result) => {
    response.setHeaders(result.headers);
    response.status(result.status).json(result.payload);
  });
});

server.listen(4000);

Logo Design

I am bad at designing so it would be great if someone can help out with this!

We put together a temporary logo but I am not satisfied with it.

Benzene HTTPRequest is incompatible with Node IncomingMessage

Using Benzene with Node http module on a TypeScript code base is a bit cumbersome because Benzene HTTPRequest is incompatible with Node IncomingMessage. The same is true for HTTPResponse and ServerResponse.

How do you propose we handle this on a TypeScript code base? Especially since the getting started guide has an example, albeit a JavaScript one, where types are used interchangeably:

const server = createServer(async (req, res) => {
  const rawBody = await readBody(req);
  const result = await graphqlHTTP({
    method: req.method,
    headers: req.headers,
    body: parseGraphQLBody(rawBody, req.headers["content-type"]),
  });
  res.writeHead(result.status, result.headers);
  res.end(JSON.stringify(result.payload));
});

I'm just looking for best practices, and recommendations :)

Spec compliance

This issue tracks the process of making Benzene libraries spec-compliance.

@benzene/http needs to be compliant with https://github.com/graphql/graphql-over-http and @benzene/ws needs to be compliant with https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md.

Overall, it is fairly good to go but we might need unit tests to confirm it.

http

  • Accepts application/graphql+json content type (#71)
  • Respond with content type application/graphql+json and consider Accept header.

ws

TBD

Add hooks API to `@benzene/ws`

We needed to add hooks API like onStart and onComplete to @benzene/ws. We use to have it (#10) but they were removed in a later release due to certain memory leak concerns.

This issue is another visit to this matter. We need to know:

  • which hooks are needed
  • implementation/api, which variables can be accessed, mutated during those lifecycles.

For inspirations, we can look at https://github.com/apollographql/subscriptions-transport-ws and https://github.com/enisdenjo/graphql-ws.

Type mismatch between graphqlHTTP({ body }) and parseGraphQLBody?

The Getting Started guide has this example:

const server = createServer(async (req, res) => {
  const rawBody = await readBody(req);
  const result = await graphqlHTTP({
    method: req.method,
    headers: req.headers,
    body: parseGraphQLBody(rawBody, req.headers["content-type"]),
  });
  res.writeHead(result.status, result.headers);
  res.end(JSON.stringify(result.payload));
});

But the body: parseGraphQLBody(rawBody, req.headers["content-type"]), line results in a type error. Which is expected because the body type is Record<string, any> | undefined, while the parseGraphQLBody return type is Record<string, any> | null, they clearly don't match.

image

If this is expected, how should it be handled? If not, can this be fixed, please?

Benzene with Nexus Error

https://nexusjs.org/
https://nexusjs.org/docs/api/make-schema#types

It gives this error, anything that can be done?

Type 'NexusGraphQLSchema' is missing the following properties from type 'GraphQLSchema': _queryType, _mutationType, _subscriptionType, _directives, and 3 more.ts(2740)
[types.d.ts(8, 5): ]()The expected type comes from property 'schema' which is declared here on type 'Options<any, any>'

Update:
I couldn't test too much yet, but basic query it works, that is a type error.

Does not work with Cloudflare Workers

Hello again,

I'm trying to implement a GraphQL server with Benzene on Cloudflare Workers, but I'm getting an error when making a request. I can't provide a reproducible project because you'd need a Cloudflare account for that, and I'm not sure if you have one. Anyway, here's the code I have so far:

const GQL = new Benzene({ schema })

const graphqlHandler = makeHandler(GQL)

async function handleBenzeneRequest(request: HTTPRequest, rawBody: string): Promise<HTTPResponse> {
    return graphqlHandler(
        {
            method: request.method,
            headers: request.headers,
            body: parseGraphQLBody(rawBody, request.headers['content-type']),
        },
        {}
    )
}

async function readRequestBody(request: Request): Promise<string> {
    const contentType = request.headers.get('content-type')

    if (contentType?.includes('application/json')) {
        return JSON.stringify(await request.json())
    }

    return URL.createObjectURL(await request.blob())
}

async function handleRequest(request: Request): Promise<Response> {
    const result = await handleBenzeneRequest(
        {
            method: request.method,
            headers: Object.fromEntries(request.headers.entries()),
        },
        await readRequestBody(request)
    )

    console.log(result.status)
    console.log(result.headers)
    console.log(JSON.stringify(result.payload))

    return new Response(
        JSON.stringify({
            request: {
                method: request.method,
                headers: Object.fromEntries(request.headers.entries()),
            },
        }),
        {
            headers: {
                'Content-Type': 'application/json; charset=UTF-8',
            },
        }
    )
}

// eslint-disable-next-line no-restricted-globals
addEventListener('fetch', (event) => {
    event.respondWith(handleRequest(event.request))
})

Making a request returns the following:

400
[
  {
    "message": "Code generation from strings disallowed for this context"
  }
]

It looks like eval() is not supported on Cloudflare Workers, see cloudflare/wrangler-legacy#1268, but I couldn't find any eval usages on my dist code. I also found intlify/vue-i18n#198, and in there it is mentioned that new Function('...') is basically a different form of eval. Looked into my dist code, and there it was, a couple of references with new Function('...'), which come from:

  • node_modules/@hoangvvo/graphql-jit/dist/execution.js
  • node_modules/@hoangvvo/graphql-jit/dist/resolve-info.js

Do you think it's possible to write this differently so that the code doesn't use eval (and related forms), and we can use Benzene with Cloudflare Workers?

(ws) Hooks API

This is the discussion thread for Hooks API. Let me know if it should stay, how it should be changed. Please know that this API is experimental and may be changed, modified at any point.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.