API Documentation
Live on this serverGenerates an Open API definition and serves Swagger UI, Redoc and Scalar.
API Browsing Documentation
Open API Documentation
GenHTTP.Modules.ApiBrowsing Package on NuGet
GenHTTP.Modules.OpenApi Package on NuGet
using GenHTTP.Api.Content;
using GenHTTP.Api.Protocol;
using GenHTTP.Modules.ApiBrowsing;
using GenHTTP.Modules.Layouting;
using GenHTTP.Modules.OpenApi;
using GenHTTP.Modules.Reflection;
using GenHTTP.Modules.Webservices;
public static class ApiDocumentationSample
{
public static IHandlerBuilder Create()
{
/*
*
* Generates an Open API definition for a web service and lets developers
* explore and try the API in their browser. The viewers are hosted by the
* server itself, so no internet connection is required.
*
* Works the same way for functional handlers and controllers.
*
* See https://genhttp.org/documentation/content/concerns/open-api/
* and https://genhttp.org/documentation/content/handlers/api-browsing/
*
*/
return Layout.Create()
.AddService<BookService>("books")
.AddOpenApi() // GET /samples/api-docs/openapi.json (or .yaml)
.AddSwaggerUi() // GET /samples/api-docs/swagger/
.AddRedoc() // GET /samples/api-docs/redoc/
.AddScalar(title: "Book API"); // GET /samples/api-docs/scalar/
}
public record Book(int Id, string Title);
public class BookService
{
private static readonly List<Book> Books =
[
new(1, "Lord of the Rings")
];
[ResourceMethod]
public List<Book> List()
{
lock (Books) return [..Books];
}
[ResourceMethod(":id")]
public Book Get(int id)
{
lock (Books)
{
return Books.FirstOrDefault(b => b.Id == id) ?? throw new ProviderException(ResponseStatus.NotFound, $"There is no book with id {id}");
}
}
[ResourceMethod(Method.Put)]
public Book Create(Book book)
{
lock (Books)
{
if (Books.Count >= 50)
{
throw new ProviderException(ResponseStatus.Conflict, "The shelf is full, please delete a book first");
}
var toAdd = book with
{
Id = Books.Select(b => b.Id).DefaultIfEmpty().Max() + 1
};
Books.Add(toAdd);
return toAdd;
}
}
[ResourceMethod(Method.Delete, ":id")]
public void Delete(int id)
{
lock (Books) Books.RemoveAll(b => b.Id == id);
}
}
}Try it
Send the requests to the sample running on this server - change the path, headers or body as you like, or copy them as curl commands.
Swagger UI
Redoc
Scalar
Fetch the Open API definition
curl -i 'https://genhttp.org/samples/api-docs/openapi.json'Fetch a book that does not exist
404, as documented in the definition
curl -i 'https://genhttp.org/samples/api-docs/books/42'