cfw-graphql-bootstrap
v1.1.2
Published
Enterprise-grade GraphQL server for Cloudflare Workers
Downloads
105
Readme
cfw-graphql-bootstrap
Enterprise-grade GraphQL server framework for Cloudflare Workers with built-in security, caching, and observability.
Features
- 🚀 Optimized for Cloudflare Workers - Built specifically for edge runtime with minimal bundle size
- 🔒 Enterprise Security - HMAC signature verification, CORS, rate limiting, and security headers
- 💾 Built-in Caching - Native Cloudflare KV support with cache-aside pattern
- 📊 Observability - Distributed tracing, structured logging with Pino, and health checks
- 🛡️ Type Safety - Full TypeScript support with proper type exports
- ⚡ High Performance - Lightweight environment parsing, efficient middleware chain
- 🔧 Developer Experience - Easy setup, extensible context, and modular architecture
Installation
npm install cfw-graphql-bootstrap
# or
bun add cfw-graphql-bootstrapPeer Dependencies
This package requires the following peer dependencies:
{
"@apollo/server": "^5.0.0",
"@cloudflare/workers-types": "^4.0.0",
"hono": "^4.0.0",
"typescript": "^5.0.0"
}Quick Start
import {
createGraphQLServer,
createSchemaModule,
gql,
} from 'cfw-graphql-bootstrap';
// Define your schema
const schema = createSchemaModule({
typeDefs: gql`
type Query {
hello(name: String!): String
}
`,
resolvers: {
Query: {
hello: (_, {name}) => `Hello ${name}!`,
},
},
});
// Create the server (cache is automatically configured)
const server = createGraphQLServer({
name: 'my-graphql-api',
version: '1.0.0',
config: {
apollo: {
schema: schema.schema,
// Cache is automatically configured from KV binding
},
// Optional: Define data sources (cache is provided)
datasources: (cache, context) => ({
// cache is Apollo's KeyValueCache<string> from KV
users: new UserDataSource(cache),
}),
},
});
// Export for Cloudflare Workers
export default server.configure();Advanced Usage
Custom Context
Extend the base context with your own properties:
import {createGraphQLServer, type BaseContext} from 'cfw-graphql-bootstrap';
interface MyContext extends BaseContext {
dataSources: {
userAPI: UserAPI;
};
}
const server = createGraphQLServer<any, MyContext>({
name: 'my-api',
version: '1.0.0',
config: {
apollo: {schema},
datasources: (cache, context) => ({
userAPI: new UserAPI(context),
}),
extendContext: async (baseContext, honoContext) => ({
...baseContext,
// Add custom context properties
}),
},
});Caching
The framework requires a KV namespace binding named KV for caching. The framework provides two cache interfaces that both use this KV storage:
- Apollo's KeyValueCache - Automatically configured for Apollo Server features (response caching, APQ)
- KVCache - Available in
context.cachefor application-level caching with enhanced features
Required Configuration:
# wrangler.toml (REQUIRED)
[[kv_namespaces]]
binding = "KV" # Must be named "KV"
id = "your-kv-namespace-id"If the KV binding is missing, the server will throw an error on startup.
// 1. Apollo cache is automatically configured from KV binding
// No need to manually pass cache!
// 2. Application cache in resolvers (context.cache is KVCache)
const resolvers = {
Query: {
user: async (_, {id}, context) => {
// Use KVCache's memoize for auto key generation
return context.cache.memoize('user', {id}, () => fetchUserFromDB(id), {
ttl: 300,
});
},
},
};
// 3. Cache decorator for class-based resolvers
import {cached} from 'cfw-graphql-bootstrap';
class UserResolver {
@cached({ttl: 300}) // Uses KVCache
async getUser(_, {id}, context) {
return fetchUserFromDB(id);
}
}Batching Data Sources
Create efficient batched data sources with automatic caching:
import {BatchingDataSource, ensureBatchOrder} from 'cfw-graphql-bootstrap';
export class UserDataSource extends BatchingDataSource<
BaseContext,
string,
User
> {
constructor() {
super(
async (ids: readonly string[]) => {
const users = await fetchUsersFromDB(ids);
return ensureBatchOrder(ids, users, 'id');
},
{cache: true}, // DataLoader options
'users' // KV cache namespace
);
}
}
// In your resolver
const user = await context.dataSources.users.load(userId);
const users = await context.dataSources.users.loadMany([id1, id2, id3]);Environment Configuration
The framework automatically validates and parses environment variables:
// Available in context.env
interface EnvConfig {
NODE_ENV: 'development' | 'test' | 'production';
PORT: number;
GATEWAY_SECRET?: string;
ALLOWED_ORIGINS: string[];
LOG_LEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
RATE_LIMIT_WINDOW_MS: number;
RATE_LIMIT_MAX: number;
// ... and more
}Middleware
Add custom middleware or configure built-in ones:
import {
createRateLimitMiddleware,
createValidationMiddleware,
createTracingMiddleware,
configureHealthChecks,
} from 'cfw-graphql-bootstrap';
// All middleware is automatically configured
// Customize if needed in your server setupLogging
Structured logging with Pino, optimized for Cloudflare Workers:
import {logger} from 'cfw-graphql-bootstrap';
logger.info({userId: '123'}, 'User action');
logger.error({err: error}, 'Operation failed');Security
Built-in security features:
- HMAC signature verification for gateway communication
- Rate limiting with Cloudflare KV
- CORS configuration
- Security headers (CSP, HSTS, etc.)
- Request validation
API Reference
Core Exports
createGraphQLServer(options)- Create a new GraphQL serverServerBuilder- Low-level server builder classcreateContextFunction(extendFn?)- Create context factory
Context & Types
BaseContext- Base context interfaceContextUser- User context typeContextExtendFunction- Context extension function type
Environment
envLoader- Environment configuration loaderEnvConfig- Environment configuration type
Cache & Data Loading
createCache(env)- Create KV cache instanceKVCache- Cloudflare KV cache implementation with memoizationApolloKVAdapter- Apollo KeyValueCache adapter for KVcreateApolloCache(kv)- Create Apollo-compatible cacheInMemoryCache- Simple in-memory cache for development@cached(options)- Cache decorator for resolver methodsCachedDataLoader- DataLoader with caching supportBatchingDataSource- Base class for batched data fetchingcreateBatchingDataSource- Factory for batching data sourcesensureBatchOrder- Helper to maintain batch order
Middleware
createRateLimitMiddleware(options)createValidationMiddleware(options)createTracingMiddleware()configureHealthChecks(app, options)
Utilities
createSchemaModule(config)- Create GraphQL schemagql- GraphQL template literal tagAppError- Application error classlogger- Pino logger instance
Deployment
Wrangler Configuration
# wrangler.toml
name = "my-graphql-api"
main = "dist/index.js"
compatibility_date = "2024-01-01"
[env.production]
vars = {
NODE_ENV = "production",
ALLOWED_ORIGINS = "https://myapp.com",
RATE_LIMIT_MAX = "100"
}
[[kv_namespaces]]
binding = "KV"
id = "your-kv-namespace-id"
[[kv_namespaces]]
binding = "RATE_LIMIT_KV"
id = "your-rate-limit-kv-id"Deploy
# Development
wrangler dev
# Production
wrangler deploy --env productionPerformance
- Bundle Size: ~32KB (ESM, before compression)
- Cold Start: < 10ms typical
- Request Overhead: < 2ms for middleware chain
- Memory Usage: Optimized for Workers' 128MB limit
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
License
MIT
Support
For issues and feature requests, please use the GitHub issue tracker.
