Exposing OpenAPI spec from the server? #736
-
I've been tinkering with One thing that I wanted to do was expose the OpenAPI spec from an endpoint, and potentially even serve a Swagger UI page from the server itself rather than just generating the spec file and dropping int on a file server somewhere. I've actually managed to do this in a test application but wasn't sure if there was a better way that I might be missing. Here's an overview of the implementation I have. Create a struct to hold the API description: pub struct MyContext {
pub api_description: String,
} Get the OpenAPI Spec and put on the context: const API_DESCRIPTION: &str = include_str!("../api-description.md");
let api_description = api
.openapi("Todo Example", "0.0.1")
.description(API_DESCRIPTION)
.json()
.unwrap()
.to_string();
let api_context = MyContext {
api_description,
}; Create handler for serving the OpenAPI spec: #[endpoint {
method = GET,
path = "/openapi.json",
unpublished = true,
}]
pub async fn get_openapi(
rqctx: RequestContext<MApiContext>,
) -> Result<HttpResponseOk<Value>, HttpError> {
let api_context = rqctx.context();
let body = serde_json::from_str(api_context.api_description.as_str()).unwrap();
Ok(HttpResponseOk(body))
} Create handler for serving the Swagger UI page: const SWAGGER_HTML: &str = include_str!("../swagger-ui.html");
#[endpoint {
method = GET,
path = "/swagger-ui",
unpublished = true,
}]
pub async fn get_swagger_ui(
_rqctx: RequestContext<MApiContext>,
) -> Result<Response<Body>, HttpError> {
Ok(Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "text/html")
.body(SWAGGER_HTML.into())?)
} Has anyone taken a different approach, or is there a better way to do this? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Looks fine to me! My first thought was to read and serve the spec file directly at request time rather than putting it on context, but this might be better. At least, it feels simpler to not have to do file I/O live. |
Beta Was this translation helpful? Give feedback.
Looks fine to me! My first thought was to read and serve the spec file directly at request time rather than putting it on context, but this might be better. At least, it feels simpler to not have to do file I/O live.