Gateweaver is an open-source, lightweight API Gateway built on Express.js, designed to streamline the connection between frontend applications and upstream APIs. It allows you to create a tailored API layer that simplifies frontend development while enhancing security and performance.
-
API Aggregation: Easily proxy and combine multiple upstream APIs into a single, frontend-friendly API, simplifying your frontend development.
-
Enhanced Security: Hide API keys and sensitive data from the client-side, keeping upstream API logic and credentials protected.
-
Flexible Configuration: Use a simple YAML file to define endpoints and apply policies, making it easy to adapt to your specific use case.
-
Performance Optimization: Tailor API responses to exactly what your frontend needs, reducing complexity and optimizing API calls.
-
Built-in Policies: Includes ready-to-use policies for CORS, JWT validation, and rate limiting.
-
Customization: Extend functionality with custom Express middleware and handlers.
-
Easy Development: Get started quickly with the node CLI or Docker image.
-
Framework and Platform Agnostic: Compatible with any frontend web or mobile framework and can integrate with various upstream API architectures.
Have a question or found a bug?
Install the Gateweaver CLI in your project using npm:
npm install @gateweaver/cli
or with Yarn:
yarn add @gateweaver/cli
or with pnpm:
pnpm add @gateweaver/cli
Create a gateweaver.yml
file in your project:
policyDefinitions:
cors:
origin: "http://localhost:3000"
global:
policies:
- cors
endpoints:
- path: "/proxy"
target:
url: "https://jsonplaceholder.typicode.com"
This example configuration creates an API Gateway that proxies all requests to JSONPlaceholder. For example:
- https://jsonplaceholder.typicode.com/todos becomes http://localhost:8080/proxy/todos
- https://jsonplaceholder.typicode.com/posts becomes http://localhost:8080/proxy/posts
- ... and any other JSONPlaceholder endpoint
Visit the Configuration docs to learn more about the available options.
To use environment variables in your configuration file, you can use the ${VAR_NAME}
syntax. Let's update our configuration to use environment variables for CORS origin and add a new endpoint that uses a bearer token:
policyDefinitions:
cors:
origin: "${CORS_ORIGIN}"
global:
policies:
- cors
endpoints:
- path: "/proxy"
target:
url: "https://jsonplaceholder.typicode.com"
- path: "/secure"
target:
url: "https://httpbin.org/bearer"
request:
headers:
Authorization: "Bearer ${API_KEY}"
This creates a new endpoint /secure
that proxies requests to httpbin.org/bearer with a bearer token in the request headers.
To set environment variables locally during development, create a .env.gateweaver
file:
CORS_ORIGIN=http://localhost:3000
API_KEY=your-api-key
Remember to add the .env.gateweaver
file to your .gitignore
file to prevent it from being committed to your repository.
Gateweaver allows you to extend its functionality with custom middleware and handlers. Here's how to use them:
- Create a custom middleware file at
middleware/custom-middleware.ts
:
import { Request, Response, NextFunction } from "express";
export function customMiddleware(
req: Request,
res: Response,
next: NextFunction,
) {
if (req.headers["x-test"] === "test") {
return next();
}
return res.status(403).send("Forbidden");
}
This middleware checks for a custom header x-test
with the value test
and allows the request to continue if it matches. It will occur before the request reaches the target endpoint.
- Create a custom handler file at
handlers/custom-handler.ts
:
import { Request, Response } from "express";
interface Post {
userId: number;
id: number;
title: string;
body: string;
}
interface TransformedPost {
id: number;
title: string;
snippet: string;
}
export const customHandler = async (_: Request, res: Response) => {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
if (!response.ok) {
throw new Error(
`Failed to fetch posts: ${response.status} ${response.statusText}`,
);
}
const posts: Post[] = await response.json();
const transformedPosts: TransformedPost[] = posts.map((post) => ({
id: post.id,
title: post.title,
snippet: post.body.slice(0, 100) + (post.body.length > 100 ? "..." : ""),
}));
res.json(transformedPosts);
} catch (error) {
console.error(error);
res
.status(500)
.json({ error: "An error occurred while processing your request" });
}
};
- Update your gateweaver.yml to include these custom components:
policyDefinitions:
cors:
origin: "${CORS_ORIGIN}"
global:
policies:
- cors
endpoints:
- path: "/proxy"
target:
url: "https://jsonplaceholder.typicode.com"
- path: "/secure"
target:
url: "https://httpbin.org/bearer"
request:
headers:
Authorization: "Bearer ${API_KEY}"
- path: "/middleware"
target:
url: "https://httpbin.org/headers"
middleware:
- path: "./middleware/custom-middleware.ts"
function: "customMiddleware"
- path: "/handler"
target:
handler:
path: "./handlers/custom-handler.ts"
function: "customHandler"
This configuration now includes:
- A proxy endpoint for all JSONPlaceholder requests
- A secure endpoint using a bearer token
- An endpoint with custom middleware
- A custom handler endpoint
Run the following command where your gateweaver.yml
and .env.gateweaver
files are located to start the Gateweaver server in watch mode. This will automatically reload the server when the configuration file changes:
npx gateweaver start -w
This command will start the Gateweaver server on port 8080 by default. You can specify a different port by setting the PORT
environment variable in your .env.gateweaver
file.
Your API Gateway is now running and you can access:
- http://localhost:8080/proxy/todos for todos data
- http://localhost:8080/proxy/posts for post data
- http://localhost:8080/secure for the secure endpoint (requires API_KEY)
- http://localhost:8080/middleware for the middleware-protected endpoint (requires x-test header)
- http://localhost:8080/handler for the custom handler endpoint
Visit the CLI Commands reference page to learn more about the available commands.
You can also run the Gateweaver server using the docker hub image (gateweaver/server) or github container registry image (ghcr.io/gateweaver/server).
The following command mounts the gateweaver.yml
configuration file and uses the environment variables defined in .env.gateweaver
to start the Gateweaver server on port 8080.
docker run \
--env-file $(pwd)/.env.gateweaver \
-v $(pwd)/gateweaver.yml:/app/gateweaver.yml \
-p 8080:8080 \
gateweaver/server:0.1.0