Add OpenAPI support for AutoRoute JSON views#2562
Add OpenAPI support for AutoRoute JSON views#2562vcombey wants to merge 22 commits intodigitallyinduced:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class OpenAPI 3 generation for IHP AutoRoute JSON views by introducing typed JSON responses on View, enriching router definitions with documentation metadata via documentRoute, and providing optional Swagger UI routes that serve the generated spec.
Changes:
- Introduces typed JSON view support (
JsonResponse+jsonTyped) and integrates runtime drift detection between documented and rendered JSON. - Adds
IHP.OpenApiSupportto generate OpenAPI 3 specs from documentedAutoRoutecontrollers and to optionally serve Swagger UI +openapi.json. - Refactors routing to use
RouteDefinition(instead of rawParser Application) so route trees can carry documentation metadata.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| ihp/Test/Test/OpenApiSupportSpec.hs | Adds end-to-end tests for typed JSON rendering, OpenAPI generation, omission rules, and Swagger UI serving |
| ihp/Test/Test/Main.hs | Registers the new OpenAPI support test suite |
| ihp/IHP/ViewSupport.hs | Adds JsonResponse and jsonTyped, and defaults json to toJSON . jsonTyped |
| ihp/IHP/ViewPrelude.hs | Re-exports IHP.OpenApiSupport from the view prelude |
| ihp/IHP/RouterSupport.hs | Introduces RouteDefinition + documentRoute metadata; adds request-time OpenAPI render validation hooks |
| ihp/IHP/OpenApiSupport.hs | Implements OpenAPI 3 spec generation + Swagger UI mounting routes |
| ihp/IHP/ControllerPrelude.hs | Re-exports IHP.OpenApiSupport from the controller prelude |
| ihp/IHP/Controller/Render.hs | Runs OpenAPI drift validation before emitting JSON responses |
| ihp/ihp.cabal | Adds openapi3 dependency, module exposure, and the new test module |
| ihp/default.nix | Adds openapi3 to the Nix derivation dependencies |
| ihp-ide/IHP/IDE/CodeGen/ApplicationGenerator.hs | Updates generated skeleton comments to mention documentRoute for OpenAPI |
| Guide/view.markdown | Documents typed JSON views (JsonResponse/jsonTyped) and OpenAPI schema workflow |
| Guide/routing.markdown | Documents documentRoute, buildOpenApi, and Swagger UI mounting |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| , json = Just do | ||
| let jsonValue = ViewSupport.json view | ||
| validateOpenApiRenderedView view jsonValue | ||
| renderJson jsonValue |
There was a problem hiding this comment.
render now always calls validateOpenApiRenderedView for documented routes, which computes jsonTyped (and toJSON) and does a full Value equality check on every JSON response. This doubles JSON construction work and can expose internal type names/error details via a 500 in production. Consider gating this validation behind Development (or a config flag), and/or ensuring the thrown message is sanitized for production.
| ) => ByteString -> RouteDefinition | ||
| webSocketAppWithCustomPath path = rawRoute do | ||
| Attoparsec.char '/' | ||
| string path |
There was a problem hiding this comment.
Changing webSocketAppWithCustomPath (and other helpers) to return RouteDefinition breaks downstream code that expects a Parser Application (e.g. ihp-ssc/IHP/ServerSideComponent/RouterFunctions.routeComponent currently returns Parser Application but calls webSocketAppWithCustomPath). To keep the monorepo building, either update those call sites to use RouteDefinition, or provide a compatibility helper (or export a conversion) for consumers that still need a Parser Application.
|
|
||
| `documentRoute` still derives the path, methods and query parameters from `AutoRoute`. It only adds the extra metadata needed for OpenAPI generation. | ||
|
|
||
| Use `documentRoute` only for controllers whose routing is fully described by `AutoRoute`. Controllers that override `customRoutes` or `customPathTo`, or controllers mounted through the lower-level parser APIs, continue to work normally at runtime but are omitted from the generated OpenAPI document on purpose. |
There was a problem hiding this comment.
This section says controllers that override customRoutes are omitted from OpenAPI generation. The current implementation only omits routes based on documentRoute metadata and (per action) customPathTo; it does not detect whether customRoutes is overridden, so such controllers/actions can still be documented if mounted with documentRoute. Please adjust the wording to match the actual behavior (e.g. customRoutes-defined endpoints aren’t generated / only pure AutoRoute-derived paths are documented).
| Use `documentRoute` only for controllers whose routing is fully described by `AutoRoute`. Controllers that override `customRoutes` or `customPathTo`, or controllers mounted through the lower-level parser APIs, continue to work normally at runtime but are omitted from the generated OpenAPI document on purpose. | |
| Use `documentRoute` only for controllers whose routing is fully described by `AutoRoute`. Only the paths, methods and query parameters that `AutoRoute` would generate are included in the OpenAPI document; endpoints introduced via `customRoutes`, controller-level `customPathTo`, or the lower-level parser APIs continue to work normally at runtime but are not represented in the generated OpenAPI document. |
|
👍 like the general idea of this, but don't want to merge larger changes for the next days so we can stabilize for ihp v1.5 release |
62f4d1b to
e955a9c
Compare
736cb93 to
b738aed
Compare
36cbc8d to
d738674
Compare
I needed json routes for a cli using my ihp app. I wanted to be fully generated and typed from the definition.
Was more easy that what I thought to add support for it in ihp, with a typedsql method and associated type in Views.
What do you think @mpscholten ?
Summary
AutoRouteJSON views viadocumentRouteViewJSON payloads and fail fast when documented JSON output drifts from the implementationopenapi3dependency so appdevenv upbuilds the forkedihppackageDetails
JsonResponse/jsonTypedsupport onViewIHP.OpenApiSupportgeneration for documentedAutoRoutecontrollers onlycomponents.schemasfor referenced response/parameter schemascustomRoutes/customPathToendpoints from the generated spec to avoid driftswaggerUi/swaggerUiWithOptionshelpers to serve Swagger UI and the generated spec from the mounted front controller