Csilk 0.2.1
A lightweight, high-performance C HTTP web framework
Loading...
Searching...
No Matches
swagger.c File Reference

OpenAPI 3.0 specification generator and Swagger UI serving. More...

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "csilk/csilk.h"
#include "csilk/reflection/reflect.h"
Include dependency graph for swagger.c:

Functions

static void path_to_openapi (const char *path, char *out, size_t out_size)
 Convert a csilk path pattern to OpenAPI 3.0 path format.
 
static const char * field_type_to_openapi_type (csilk_field_type_t type)
 Map a csilk reflection field type to an OpenAPI 3.0 schema type string.
 
static cJSON * generate_schema_for_type (const char *type_name)
 Generate an OpenAPI 3.0 schema object for a registered reflection type.
 
static void add_schema (cJSON *schemas, const char *type_name)
 Internal: add a schema definition to the components/schemas map.
 
static void auto_register_schema (const char *name, const csilk_reflect_entry_t *entry, void *user_data)
 Internal: callback for csilk_reflect_foreach() to auto-register a schema.
 
cJSON * csilk_generate_openapi_json (csilk_router_t *router, const char *title, const char *version, const char *description)
 Generate a complete OpenAPI 3.0 specification document from the router and reflection registry.
 
void csilk_serve_openapi (csilk_ctx_t *c, csilk_router_t *r, const char *title, const char *version, const char *description)
 Serve the generated OpenAPI 3.0 spec as a JSON response.
 
void csilk_serve_swagger_ui (csilk_ctx_t *c)
 Serve the embedded Swagger UI page. The page loads /openapi.json at runtime to render interactive documentation.
 

Variables

static const char swagger_ui_html []
 Compiled-in Swagger UI HTML page.
 

Detailed Description

OpenAPI 3.0 specification generator and Swagger UI serving.

Architecture: The OpenAPI document builder (csilk_generate_openapi_json) works in three phases: (1) traversing the route table to populate the "paths" section with endpoint descriptions, parameters, request bodies, and responses; (2) calling add_schema() on each unique input/output type to populate "components/schemas" with JSON Schema objects derived from the reflection registry; (3) scanning all registered reflection types via csilk_reflect_foreach() to ensure even orphan types appear in the spec.

Path patterns from the router (":param", "*glob") are converted to OpenAPI 3.0 syntax ("{param}", "{glob+}") by path_to_openapi(). Schema generation uses generate_schema_for_type() to walk each reflection type's field descriptors and emit "type" + "properties" maps, with nested structs emitting "$ref" references. Circular type references are handled by add_schema()'s cycle detection (checks type presence before recursing).

The Swagger UI page is compiled into the binary as a static string and served at a designated route by csilk_serve_swagger_ui(). It loads the /openapi.json endpoint at runtime.

Function Documentation

◆ add_schema()

static void add_schema ( cJSON *  schemas,
const char *  type_name 
)
static

Internal: add a schema definition to the components/schemas map.

If the schema for type_name already exists in schemas, this is a no-op (prevents infinite recursion on circular type references). Otherwise generates the schema, adds it, and recursively registers schemas for any nested struct fields.

Parameters
schemasThe "schemas" cJSON object under components.
type_nameType name to generate and add.

◆ auto_register_schema()

static void auto_register_schema ( const char *  name,
const csilk_reflect_entry_t entry,
void *  user_data 
)
static

Internal: callback for csilk_reflect_foreach() to auto-register a schema.

Calls add_schema() for every type found during iteration. Used to ensure all registered types appear in components/schemas even if not explicitly linked to any route.

Parameters
nameType name.
entryReflection entry (unused).
user_dataPointer to the schemas cJSON object.

◆ csilk_generate_openapi_json()

cJSON * csilk_generate_openapi_json ( csilk_router_t router,
const char *  title,
const char *  version,
const char *  description 
)

Generate a complete OpenAPI 3.0 specification document from the router and reflection registry.

Generate an OpenAPI 3.0 specification JSON from the router.

Builds the full OpenAPI JSON structure including:

  • openapi version field ("3.0.3")
  • info section (title, version, description)
  • paths section (one entry per route, with parameters, requestBody, and responses)
  • components/schemas section (auto-generated from all registered reflection types)

Path parameters are extracted from the route patterns and converted to OpenAPI format. Request/response schemas are generated from input_type and output_type metadata using the reflection engine.

Parameters
routerThe router instance containing registered routes.
titleAPI title for the info section (pass NULL for default).
versionAPI version string (pass NULL for default "1.0.0").
descriptionAPI description (may be NULL).
Returns
A cJSON object representing the full OpenAPI document. Caller must free with cJSON_Delete(). Returns NULL if router is NULL or allocation fails.

◆ csilk_serve_openapi()

void csilk_serve_openapi ( csilk_ctx_t *  c,
csilk_router_t r,
const char *  title,
const char *  version,
const char *  description 
)

Serve the generated OpenAPI 3.0 spec as a JSON response.

Serve the OpenAPI JSON specification as the response.

Intended to be called from within a route handler. Generates the OpenAPI document via csilk_generate_openapi_json() and sends it as a JSON response.

Parameters
cThe request context.
rThe router instance.
titleAPI title.
versionAPI version.
descriptionAPI description.
Note
The response is sent synchronously via csilk_json(). On failure, a 500 error response is sent.

◆ csilk_serve_swagger_ui()

void csilk_serve_swagger_ui ( csilk_ctx_t *  c)

Serve the embedded Swagger UI page. The page loads /openapi.json at runtime to render interactive documentation.

Serve the embedded Swagger UI page.

◆ field_type_to_openapi_type()

static const char * field_type_to_openapi_type ( csilk_field_type_t  type)
static

Map a csilk reflection field type to an OpenAPI 3.0 schema type string.

Integer types map to "integer", float/double to "number", bool to "boolean", string to "string", and struct to "object". Any unrecognized type defaults to "string".

Parameters
typeThe csilk_field_type_t enum value.
Returns
A static string literal suitable for OpenAPI's "type" field.

◆ generate_schema_for_type()

static cJSON * generate_schema_for_type ( const char *  type_name)
static

Generate an OpenAPI 3.0 schema object for a registered reflection type.

Iterates the type's field descriptors and produces a schema with "type": "object" and a "properties" map. Each field is mapped to its OpenAPI type, with nested structs rendered as $ref pointers to #/components/schemas/<type_name>. Array fields use an "array" type wrapper with "items".

Parameters
type_nameRegistered reflection type name.
Returns
A cJSON object representing the OpenAPI schema, or NULL if the type is not registered or allocation fails.
Note
The caller must free the returned cJSON with cJSON_Delete().

◆ path_to_openapi()

static void path_to_openapi ( const char *  path,
char *  out,
size_t  out_size 
)
static

Convert a csilk path pattern to OpenAPI 3.0 path format.

Transforms ":param" segments to "{param}" and "*wildcard" segments to "{wildcard+}" as required by the OpenAPI 3.0 specification.

Parameters
pathInput path pattern (e.g., "/users/:id/posts/star-path").
outOutput buffer for the OpenAPI-formatted path.
out_sizeSize of the output buffer (including null terminator).
Note
The output is truncated to fit out_size if the converted path is too long. The caller should ensure out_size is large enough.

Variable Documentation

◆ swagger_ui_html

const char swagger_ui_html[]
static

Compiled-in Swagger UI HTML page.

This HTML string is embedded directly into the binary and served at a designated route by csilk_serve_swagger_ui(). It initializes the Swagger UI JavaScript bundle to render an interactive API reference.

Loading strategy:

  • CSS/JS assets are hosted at "/csilk-docs/" — these are static files from the official Swagger UI distribution bundled with the server (either as separate files or embedded via a build step).
  • The spec URL is "/openapi.json", served by csilk_serve_openapi(). This decouples UI from spec generation: the UI HTML is loaded once, and the spec is fetched on page load, always reflecting the latest routes and types without a server restart.
  • SwaggerUIBundle + SwaggerUIStandalonePreset provide the full "Try it out" feature, response preview, and schema exploration.