Benzene

benzene

Benzene is a fast and minimal JavaScript GraphQL Server. In Chemistry, it is a building block chemical. In JavaScript, it is the building block for your next API.

Overview

import express from "express";
import { Benzene, makeHandler } from "@benzene/http";
const app = express();
const GQL = new Benzene();
const graphqlHTTP = makeHandler(GQL);
app.use("/graphql", async (req, res) => {
const result = await graphqlHTTP({
method: req.method,
query: req.query,
body: req.body,
headers: req.headers,
});
res.header(result.headers);
res.status(result.status).send(result.payload);
});
app.listen(4000);

In this example, we create a GraphQL handler graphqlHTTP using a Benzene instance. The instance will also be used in other libraries like @benzene/ws, allowing us to unify pipelines like error formatting in one place.

graphqlHTTP accepts a generic request object containing method, query, body, and headers and returns a generic response object containing status, headers, and payload. This allows it to work with any frameworks (or even runtimes).

As we can see, graphqlHTTP does nothing but executing the GraphQL request as it is, giving us full control in aspects like CORS or body parsing.

Features

The @benzene/http and @benzene/ws packages allow us to build a full-featured GraphQL server, featuring:

  • Super minimal and performant. @benzene/http and @benzene/ws purely wrap @benzene/core, which includes minimal dependencies and features no third-party integrations, thus avoiding unnecessary overheads.
  • Transport & Framework agnostic. Each package features generic Request, Response, or WebSocket interfaces to easily plug into any JavaScript frameworks or runtimes.
  • Unopinionated and observable APIs. Benzene does not include any middleware or configurations, so we can be in total control of logging, parsing, and error handling.
  • Unified pipeline. Write error handling or context creation function only once. Every transport handler inherits the same Benzene instance and takes advantage of its shared configuration.
  • Fully extensible. Despite not being battery-included, it can be extended with recipes (like Persisted queries) or @benzene/extra.

We are taking an approach opposite to Apollo Server, which abstracts everything behind its applyMiddleware function that includes unexpected and hard-to-customized "defaults". While our approach requires a bit more boilerplate, we achieve an observable and customizable server integration.