Generate Effect HttpApi server code from OpenAPI 3.1 specifications.
- 🚀 Complete Code Generation: Generates fully-typed Effect HttpApi server code
- 📊 Schema Validation: Effect Schema definitions for request/response validation
- 🔧 OpenAPI 3.1 Support: Full support for OpenAPI 3.1 specification features
- 📝 Multiple Formats: Supports both YAML and JSON OpenAPI specifications
- 🎯 Type Safety: Generated code is fully type-safe with Effect's type system
- ⚡ CLI Ready: Command-line interface for easy integration into build pipelines
- 🧪 Well Tested: Comprehensive test suite with 44+ tests including integration tests
npm install effect-openapi-server-gen
# or
yarn add effect-openapi-server-gen
# or
pnpm add effect-openapi-server-genGenerate Effect HttpApi code from an OpenAPI specification:
# From YAML file
npx effect-openapi-server-gen --output ./generated petstore.yaml
# From JSON file
npx effect-openapi-server-gen --output ./api-types petstore.json
# Specify format explicitly
npx effect-openapi-server-gen --format yaml --output ./generated spec.yml<spec>: Path to OpenAPI specification file (YAML or JSON)--output: Output directory (default:./generated)--format: Input format -auto,json, oryaml(default:auto)
The CLI generates the following files:
generated/
├── schemas.ts # Effect Schema definitions
├── endpoints.ts # HttpApiGroup with all endpoints
├── api.ts # Complete HttpApi
└── index.ts # Re-exports all modules
You can also use the library programmatically:
import { Effect } from "effect"
import {
parseOpenAPI,
generateSchemasFromComponents,
generateHttpApiGroup,
generateFullHttpApi
} from "effect-openapi-server-gen"
const generateCode = Effect.gen(function* () {
// Parse OpenAPI spec
const spec = yield* parseOpenAPI({
openapi: "3.1.0",
info: { title: "My API", version: "1.0.0" },
paths: {
"/users": {
get: {
operationId: "getUsers",
responses: {
"200": {
description: "List of users",
content: {
"application/json": {
schema: {
type: "array",
items: { $ref: "#/components/schemas/User" }
}
}
}
}
}
}
}
},
components: {
schemas: {
User: {
type: "object",
required: ["id", "name"],
properties: {
id: { type: "integer" },
name: { type: "string" }
}
}
}
}
})
// Generate schemas
const schemas = yield* generateSchemasFromComponents(spec.components)
// Generate API group
const apiGroup = yield* generateHttpApiGroup(spec)
// Generate full API
const fullApi = yield* generateFullHttpApi(spec)
return { schemas, apiGroup, fullApi }
})Given this OpenAPI specification:
openapi: 3.1.0
info:
title: Pet Store API
version: 1.0.0
paths:
/pets:
get:
operationId: listPets
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
responses:
'200':
description: List of pets
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
components:
schemas:
Pet:
type: object
required: [id, name, status]
properties:
id:
type: integer
name:
type: string
status:
type: string
enum: [available, pending, sold]The generated code includes:
schemas.ts:
import { Schema } from "@effect/schema"
export const Pet = Schema.Struct({
id: Schema.Number,
name: Schema.String,
status: Schema.Literal("available", "pending", "sold")
})endpoints.ts:
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "@effect/platform"
export const petStoreApiGroup = HttpApiGroup.make('PetStoreApi')
.add([
listPets
])api.ts:
import { HttpApi } from "@effect/platform"
export const petStoreApi = HttpApi.make('PetStoreApi')
.addGroup(petStoreApiGroup)This package supports the full range of OpenAPI 3.1 features:
- ✅ Primitive types (string, number, integer, boolean)
- ✅ Complex objects with nested properties
- ✅ Arrays with typed items
- ✅ Enums and literal values
- ✅ Optional vs required properties
- ✅ Schema references (
$ref)
- ✅ All HTTP methods (GET, POST, PUT, DELETE, PATCH, etc.)
- ✅ Path parameters with validation
- ✅ Query parameters with type coercion
- ✅ Request body validation
- ✅ Response schema validation
- ✅ Multiple response status codes
- ✅ Components and reusable schemas
- ✅ Operation IDs for endpoint naming
- ✅ Parameter validation and transformation
- ✅ Content type handling
- ✅ Comprehensive error handling
The package generates validation utilities for runtime type checking:
import { createRequestValidator, createResponseValidator } from "effect-openapi-server-gen"
// Create validators from OpenAPI operations
const requestValidator = yield* createRequestValidator(operation)
const responseValidator = yield* createResponseValidator(operation.responses)
// Validate incoming requests
const validatedRequest = yield* requestValidator({
params: { id: 123 },
query: { limit: 10 },
body: { name: "Fluffy", status: "available" }
})
// Validate outgoing responses
const validatedResponse = yield* responseValidator({
status: 200,
body: { id: 123, name: "Fluffy", status: "available" }
})The generated code is designed to work seamlessly with Effect's HttpApi:
import { HttpApiBuilder } from "@effect/platform"
import { petStoreApi } from "./generated"
const implementation = HttpApiBuilder.make(petStoreApi).pipe(
HttpApiBuilder.handle("listPets", ({ query }) =>
Effect.succeed([
{ id: 1, name: "Fluffy", status: "available" as const }
])
),
// ... handle other endpoints
)This project follows Test-Driven Development (TDD) practices:
# Run tests
pnpm test
# Run tests in watch mode
pnpm test --watch
# Type checking
pnpm run typecheck
# Linting
pnpm run lint
# Build
pnpm run buildParses and validates an OpenAPI 3.1 specification.
Generates Effect Schema definitions from OpenAPI component schemas.
generateHttpApiEndpoint(path: string, method: string, operation: OperationObject): Effect<string, EndpointGenerationError>
Generates a single HttpApiEndpoint from an OpenAPI operation.
Generates an HttpApiGroup containing all endpoints from the specification.
Generates a complete HttpApi with all groups and endpoints.
Creates a request validator function from an OpenAPI operation.
Creates a response validator function from OpenAPI response definitions.
validateRequest(request: Request, schemas: RequestValidationSchemas): Effect<ValidatedRequest, ValidationError>
Validates a request against provided schemas.
validateResponse(response: Response, schemas: ResponseValidationSchemas): Effect<ValidatedResponse, ValidationError>
Validates a response against provided schemas.
- Fork the repository
- Create a feature branch
- Write tests for your changes
- Implement your changes
- Ensure all tests pass
- Submit a pull request
MIT
- Effect - The Effect TypeScript framework
- OpenAPI Specification - API specification standard
- @effect/platform - Effect's HTTP platform
- @effect/schema - Effect's schema validation library