Open-source Ruby framework · Engineering case study
RubstAPI
Bringing a typed, documentation-first API development experience to Ruby—without asking Ruby to pretend it is Python.
Ruby has mature web frameworks, but building a focused JSON API often means assembling validation, serialization, dependency management, security declarations, documentation, and testing from separate libraries. RubstAPI explores a more cohesive answer: define the contract once and let the framework carry that intent through the entire request lifecycle.
The project is inspired by the developer experience of Python’s FastAPI, but its implementation is deliberately Ruby-native. It is a Rack-compatible callable built around explicit Ruby declarations—not an emulation layer, a Python bridge, or a source-compatibility exercise.
The design question
What if the route declaration were the source of truth?
A RubstAPI endpoint describes where each input originates, which Ruby type it should become, which constraints apply, and what shape the response promises. Those declarations drive request coercion, structured validation errors, JSON Schema, and the final OpenAPI 3.1 document.
APP.post("/items", params: {
item: RubstApi.Body(Item)
}, response_model: Item, status_code: 201) do |item:|
item
end
The endpoint receives a validated model. There is no duplicate controller branch for parsing the body, checking constraints, and constructing an error response. Invalid input is rejected before application logic runs with a machine-readable 422 response.
Framework surface
One small system, several connected concerns.
The public API covers typed path, query, header, cookie, form, file, and JSON body parameters; nested Ruby models; cached dependency graphs; security schemes; routers; middleware; response classes; background tasks; a test client; and a command-line runner.
“The goal is not the largest possible framework. It is a coherent one—where validation, documentation, testing, and runtime behavior agree.”
Keeping those capabilities connected demanded careful boundary design. Models must serialize predictably and also emit standards-compliant schemas. Security helpers must participate in request handling and OpenAPI generation. Dependency overrides must be ergonomic enough for tests without weakening per-request caching behavior.
Production-shaped proof
A sample application that tests the promise.
The companion sample project demonstrates a complete API with typed inputs, model constraints, automatic errors, response schemas, Swagger UI, ReDoc, health checks, Docker Compose, and live HTTP smoke tests. It resolves RubstAPI from RubyGems, making the example a consumer of the published package rather than a privileged local checkout.
- Standards-first architecture OpenAPI 3.1 and JSON Schema emerge from application declarations.
- Rack compatibility The application can sit naturally inside the broader Ruby web ecosystem.
- Testable dependency design Cached dependencies and application-level overrides support focused tests.
- Operational honesty Documentation distinguishes the early-stage framework from production guarantees it has not yet earned.
The takeaway
Developer experience is architecture.
RubstAPI is a study in making strong defaults feel lightweight. Its value is not only fewer lines of setup; it is the reduction of disagreement between code, validation, documentation, and tests.