Standard library · Network

net/http/swagger

Writing OpenAPI documentation for an API and serving the documentation page.

import net.http.swagger

Swagger builds the documentation of an API in the standard OpenAPI form and serves a page for looking at it and trying it out. Route picks one operation, and the functions after it, such as Summary and Returns, describe that one.

The schema of a body or a response is built from a sample value; pass an empty struct and its fields, under their @json names, appear in the documentation. Missing shows the routes that are not documented yet.

Types

Param

struct Param
One parameter.
NameTypeDescription
namestr = ""The name.
locstr = "query"Where it sits: query, header, cookie or path.
requiredbool = falseIt is required.
descriptionstr = ""The description.
schemastr = "{"type":"string"}"The schema.
net-http-swagger-Build.salam
import net.http.swagger
import encoding.json

struct Book:
    @json "id"
    pub id: int = 0
    @json "title"
    pub title: str = ""
end

func main:
    mut doc := swagger.New("library", "1.2.0")
    swagger.Describe(doc, "a sample API for books")
    swagger.Server(doc, "https://api.example.com", "the main one")
    swagger.Contact(doc, "the Salam team", "https://salamlang.ir", "team@salamlang.ir")
    swagger.License(doc, "MIT", "https://opensource.org/licenses/MIT")
    swagger.BearerAuth(doc, "token", "JWT")
    swagger.ApiKeyAuth(doc, "key", "header", "X-API-Key")
    _ := swagger.Route(doc, "GET", "/books/:id")
    swagger.Summary(doc, "one book")
    swagger.Details(doc, "Returns the book with this id.")
    swagger.Tag(doc, "books")
    swagger.OperationId(doc, "getBook")
    swagger.PathParam(doc, "id", "the id of the book")
    swagger.Query(doc, "fields", "the fields asked for", false)
    swagger.QueryTyped(doc, "limit", "the greatest number", false, 10)
    mut orders := Vector {} as Vector<str>
    orders.push("title")
    orders.push("id")
    swagger.QueryEnum(doc, "sort", "the order", false, orders)
    swagger.Header(doc, "X-Trace", "the trace id", false)
    swagger.Cookie(doc, "sid", "the session", false)
    swagger.Secure(doc, "token")
    swagger.Returns(doc, 200, "the book", Book {})
    swagger.ReturnsHeader(doc, 200, "ETag", "the version")
    swagger.ReturnsNothing(doc, 404, "not found")
    _ := swagger.Route(doc, "POST", "/books")
    swagger.Accepts(doc, "the new book", Book {})
    swagger.Returns(doc, 201, "created", Book {})
    _ := swagger.Route(doc, "PUT", "/books/:id/cover")
    swagger.AcceptsRaw(doc, "the cover image", "image/png", "{\"type\":\"string\",\"format\":\"binary\"}", true)
    swagger.ReturnsText(doc, 200, "done")
    _ := swagger.Route(doc, "POST", "/books/:id/notes")
    swagger.AcceptsOptional(doc, "the note", Book {})
    swagger.AcceptsForm(doc, "the form", Book {})
    swagger.ReturnsRaw(doc, 200, "the export", "text/csv", "{\"type\":\"string\"}")
    swagger.ReturnsHtml(doc, 200, "the page")
    swagger.ReturnsFile(doc, 200, "the file", "application/pdf")
    swagger.Deprecated(doc)
    println swagger.At(doc, "get", "/books/:id"), swagger.At(doc, "GET", "/nope")
    println doc.ops.len(), doc.ops[0].params.len(), doc.ops[0].replies.len(), doc.ops[3].is_deprecated, doc.schemes.len()
    text := swagger.Spec(doc)
    println json.Valid(text), json.Get(text, "openapi")
    println swagger.SpecIndent(doc).len() > text.len()
    println swagger.Problems(doc).len(), swagger.Undocumented(doc)
    println swagger.WriteSpec(doc, "openapi.json"), swagger.SpecFromFile("openapi.json").len() > 0, swagger.SpecFromFile("missing.json")
    println swagger.TEXT_SCHEMA, swagger.JSON_TYPE
    swagger.Free(doc)
end
Outputtrue false 4 6 2 true 2 true 3.1.0 true 0 [] true true {"type":"string"} application/json

Reply

struct Reply
One response.
NameTypeDescription
codeint = 200The status code.
descriptionstr = ""The description.
schemastr = ""The schema of the body.
content_typestr = "application/json"The content type.
header_namesVectorThe names of the response headers.
header_notesVectorThe note on each of them.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Scheme

struct Scheme
One authentication scheme.
NameTypeDescription
namestr = ""The name.
kindstr = "http"The kind: http or apiKey.
schemestr = "bearer"For http, such as bearer.
formatstr = ""The token format, such as JWT.
locstr = "header"Where the key sits.
paramstr = ""The name of the key parameter.
descriptionstr = ""The description.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Op

struct Op
One operation: one method on one path.
NameTypeDescription
methodstr = ""The method.
patternstr = ""The path pattern.
op_idstr = ""The operation id.
summarystr = ""The summary.
descriptionstr = ""The description.
is_deprecatedbool = falseIt is deprecated.
tagsVectorThe tags.
paramsVectorThe parameters.
repliesVectorThe responses.
securityVectorThe authentication schemes it requires.
body_schemastr = ""The schema of the body.
body_descriptionstr = ""The description of the body.
body_requiredbool = trueThe body is required.
body_content_typestr = "application/json"The content type of the body.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Definition

struct Definition
The definition of one type in the schema.
NameTypeDescription
namestr = ""The name.
bodystr = ""The JSON schema.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Doc

struct Doc
The OpenAPI document being built.
NameTypeDescription
titlestr = "API"The title of the API.
versionstr = "1.0.0"The version.
descriptionstr = ""The description.
serversVectorThe server addresses.
server_notesVectorThe note on each server.
opsVectorThe operations.
defsVectorThe type definitions.
schemesVectorThe authentication schemes.
contact_namestr = ""The contact name.
contact_urlstr = ""The contact address.
contact_emailstr = ""The contact email.
license_namestr = ""The licence name.
license_urlstr = ""The licence address.
curint = -1The index of the current operation; the describing functions act on that one.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Constants and variables

JSON_TYPE

const JSON_TYPE: str = "application/json"
The JSON content type.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

TEXT_TYPE

const TEXT_TYPE: str = "text/plain; charset=utf-8"
The plain text content type.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

HTML_TYPE

const HTML_TYPE: str = "text/html; charset=utf-8"
The HTML content type.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

FORM_TYPE

const FORM_TYPE: str = "application/x-www-form-urlencoded"
The form content type.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

TEXT_SCHEMA

const TEXT_SCHEMA: str = "{"type":"string"}"
The string schema.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

BINARY_SCHEMA

const BINARY_SCHEMA: str = "{"type":"string","format":"binary"}"
The binary data schema, for files.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Functions

New

func New(title: str, version: str): Doc
A new document with a title and a version.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Describe

func Describe(d &: Doc, text: str)
The overall description of the API.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Server

func Server(d &: Doc, url: str, note: str)
Adds a server address with a note.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Contact

func Contact(d &: Doc, name: str, url: str, email: str)
The contact details.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

License

func License(d &: Doc, name: str, url: str)
The licence.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

BearerAuth

func BearerAuth(d &: Doc, name: str, format: str)
Defines authentication with a Bearer token.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

ApiKeyAuth

func ApiKeyAuth(d &: Doc, name: str, loc: str, param: str)
Defines authentication with an API key in a header, the query or a cookie.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Route

func Route(d &: Doc, method: str, pattern: str): int
Adds an operation for a method and path, or picks it when it is already there, and returns its index. The :name parameters of the path are registered by themselves.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

At

func At(d &: Doc, method: str, pattern: str): bool
Picks an existing operation; false when there is none.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Summary

func Summary(d &: Doc, text: str)
The summary of the current operation.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Details

func Details(d &: Doc, text: str)
The full description.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Tag

func Tag(d &: Doc, name: str)
A tag for grouping on the page.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

OperationId

func OperationId(d &: Doc, id: str)
The unique id of the operation, for code generating tools.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Deprecated

func Deprecated(d &: Doc)
Marks the operation deprecated.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Secure

func Secure(d &: Doc, scheme: str)
Makes a defined authentication scheme a requirement of the operation.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Query

func Query(d &: Doc, name: str, description: str, required: bool)
A string query parameter.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

QueryTyped

func QueryTyped<T>(d &: Doc, name: str, description: str, required: bool, sample: T)
A query parameter whose type is taken from a sample value.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

QueryEnum

func QueryEnum(d &: Doc, name: str, description: str, required: bool, values: Vector<str>)
A query parameter with a set of allowed values.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

func Header(d &: Doc, name: str, description: str, required: bool)
A header parameter.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

func Cookie(d &: Doc, name: str, description: str, required: bool)
A cookie parameter.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

PathParam

func PathParam(d &: Doc, name: str, description: str)
The description of one path parameter.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Accepts

func Accepts<T>(d &: Doc, description: str, sample: T)
A JSON body with the schema of a sample type.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

AcceptsOptional

func AcceptsOptional<T>(d &: Doc, description: str, sample: T)
The same, with the body optional.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

AcceptsRaw

func AcceptsRaw(d &: Doc, description: str, content_type: str, schema: str, required: bool)
A body with a content type and a schema of your own.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

AcceptsForm

func AcceptsForm<T>(d &: Doc, description: str, sample: T)
A form body with the fields of a sample type.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Returns

func Returns<T>(d &: Doc, code: int, description: str, sample: T)
A JSON response with a code and the schema of a sample type.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

ReturnsRaw

func ReturnsRaw(d &: Doc, code: int, description: str, content_type: str, schema: str)
A response with any content type and schema.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

ReturnsText

func ReturnsText(d &: Doc, code: int, description: str)
A text response.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

ReturnsHtml

func ReturnsHtml(d &: Doc, code: int, description: str)
An HTML response.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

ReturnsFile

func ReturnsFile(d &: Doc, code: int, description: str, content_type: str)
A file response with a content type.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

ReturnsHeader

func ReturnsHeader(d &: Doc, code: int, name: str, description: str)
Adds a header to the response with this code.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

ReturnsNothing

func ReturnsNothing(d &: Doc, code: int, description: str)
A response with no body, such as a 204 or a 404.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Spec

func Spec(d: Doc): str
Turns the document into OpenAPI 3.1 JSON.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

SpecIndent

func SpecIndent(d: Doc): str
The same, readable with indenting.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Mount

func Mount(d: Doc, r &: router.Router, prefix: str)
Adds the documentation page and openapi.json to the router under the given prefix.
net-http-swagger-Serve.salam
import net.http
import net.http.swagger
import net.router
import str

func list(ctx: i64):
    http.Ctx_json(ctx, "[]")
end

func main:
    mut r := router.NewRouter()
    router.Get(r, "/books", list)
    router.Post(r, "/books", list)
    router.Get(r, "/admin/stats", list)
    mut doc := swagger.New("library", "1.0.0")
    println swagger.Missing(doc, r)
    swagger.ScanPrefix(doc, r, "/books")
    println doc.ops.len(), swagger.Missing(doc, r)
    swagger.Scan(doc, r)
    println doc.ops.len(), swagger.Missing(doc, r).len()
    swagger.Mount(doc, r, "/docs")
    mut server := http.NewServer(19627)
    http.Use(server, r)
    _ := http.RunBackground(server)
    spec := http.Get("http://127.0.0.1:19627/docs/openapi.json")
    println http.Status(spec), str.Contains(http.Body(spec), "/admin/stats")
    page := http.Get("http://127.0.0.1:19627/docs")
    println str.Contains(http.Body(page), "<html")
    mut r2 := router.NewRouter()
    swagger.MountSpec("{\"openapi\":\"3.1.0\"}", "ready made", r2, "/spec")
    println r2.routes.len()
    println swagger.Serve(doc, 19628), http.Status(http.Get("http://127.0.0.1:19628/openapi.json"))
    println swagger.ServeSpec("{\"openapi\":\"3.1.0\"}", "another", 19629)
    println str.Contains(swagger.Page("API", "/openapi.json"), "/openapi.json")
end
Output["GET /books", "POST /books", "GET /admin/stats"] 2 ["GET /admin/stats"] 3 0 200 true true 3 true 200 true true

MountSpec

func MountSpec(spec: str, title: str, r &: router.Router, prefix: str)
The same, with a ready made spec.

The example for this item is shown with the ones above: net-http-swagger-Serve.salam

Serve

func Serve(d: Doc, port: int): bool
Runs the documentation page on a port of its own in the background.

The example for this item is shown with the ones above: net-http-swagger-Serve.salam

ServeSpec

func ServeSpec(spec: str, title: str, port: int): bool
The same, with a ready made spec.

The example for this item is shown with the ones above: net-http-swagger-Serve.salam

SpecFromFile

func SpecFromFile(path: str): str
Reads a ready made spec from a file; an empty string when there is none.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

WriteSpec

func WriteSpec(d: Doc, path: str): bool
Writes the document to a file.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Problems

func Problems(d: Doc): Vector<str>
The faults of the document: an empty title or version, a duplicate id and the like.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Undocumented

func Undocumented(d: Doc): Vector<str>
The operations with no summary, description or response.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Missing

func Missing(d: Doc, r: router.Router): Vector<str>
The routes of the router that are not in the document.

The example for this item is shown with the ones above: net-http-swagger-Serve.salam

Free

func Free(d &: Doc)
Frees the memory of the document.

The example for this item is shown with the ones above: net-http-swagger-Build.salam

Page

func Page(title: str, spec_url: str): str
The HTML of the documentation page, which reads the spec from the given address.

The example for this item is shown with the ones above: net-http-swagger-Serve.salam

Scan

func Scan(d &: Doc, r: router.Router)
Makes an operation for every route of the router, so you can describe them afterwards.

The example for this item is shown with the ones above: net-http-swagger-Serve.salam

ScanPrefix

func ScanPrefix(d &: Doc, r: router.Router, prefix: str)
The same, for the routes under this prefix only.

The example for this item is shown with the ones above: net-http-swagger-Serve.salam