UNPKG

fluid-oas

Version:

Build declarative OpenApiv3.* specifications.

282 lines (239 loc) 6.92 kB
# Fluid-OAS Declaratively build _type-safe_ **HTTP APIs** in TypeScript through the **OpenAPI** specification. ## Installation With npm: ```bash npm install fluid-oas --save-dev ``` With Bun: ```bash bun add --development fluid-oas ``` Visit the [docs](https://stoneliucs.github.io/fluid-oas/) here 1. [Overview](#overview) - [Example Usage](#example-usage) 2. [Schema Design](#schemas) - [Primitives](#primitive-data-types) - [Objects](#objects) - [Arrays](#arrays) ## Overview _Fluid-OAS_ is an embedded, completely functional _domain specific language_ for expressing type-safe HTTP APIs written in TypeScript through the OpenAPI specification. - No dependencies, use as is. - Write the most complex OpenAPI specification you want, use whatever framework you want. - Focus on core business logic, design systems in an _API-first manner_. - Leverage TypeScript's advanced type-system to get autocomplete and compile-time checks for building your OpenAPI specification. - Significantly reduce the amount of boilerplate JSON your team has to write. ### Example Usage ```ts const info = Info.addTitle("My API") .addVersion("1.0.0") .addDescription("Example description.") .addSummary("Example Summary") .addContact( // Add contact information if needed. Contact.addEmail("youremail@blah.com") .addName("Your Name.") .addUrl("https://domain.com") ); // Example schemas const nameSchema = Union( String.addMinLength(1) .addMaxLength(10) .addExample(Example.addValue("John")) .addDescription("Name of the person."), Null ); const uuidSchema = String.addFormat("uuid") .addExample("5e91507e-5630-4efd-9fd4-799178870b10") // Examples are supported but are deprecated as of 3.0.0 .addDescription("Unique identifer"); const userSchema = Object.addProperties({ firstName: nameSchema, lastName: nameSchema, id: uuidSchema, }).addRequired(["id"]); // id is required an should match the id key in the Object. const errorSchema = Object.addProperties({ message: String.addReadOnly(true), }); const getUserResponses = Responses.addResponses({ 200: Response.addDescription("Successfully Retrieved User!").addContents({ "application/json": MediaType.addSchema(userSchema), }), 401: Response.addDescription("Failed to retrieve user!").addContents({ "application/json": MediaType.addSchema(errorSchema), }), }); // Declare Path Items const getUser = PathItem.addMethod({ get: Operation.addParameters([ Parameter.schema .addName("id") .addIn("path") .addRequired(true) .addSchema(uuidSchema), ]).addResponses(getUserResponses), }); // Register Paths const path = Path.beginGroup("/api/v1") .addEndpoints({ "/user/{id}": getUser }) .endGroup(); const oas = OpenApiV3.addOpenApiVersion("3.1.1").addInfo(info).addPaths(path); // Write OAS Spec oas.writeOASSync(); ``` ```json { "openapi": "3.1.1", "info": { "summary": "Example Summary", "description": "Example description.", "title": "My API", "version": "1.0.0", "contact": { "name": "Your Name.", "url": "https://domain.com", "email": "youremail@blah.com" } }, "paths": { "/api/v1/user/{id}": { "get": { "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "description": "Unique identifer", "example": "5e91507e-5630-4efd-9fd4-799178870b10", "format": "uuid", "type": "string" } } ], "responses": { "200": { "description": "Successfully Retrieved User!", "content": { "application/json": { "schema": { "properties": { "firstName": { "type": ["string", "null"], "description": "Name of the person.", "example": { "value": "John" }, "minLength": 1, "maxLength": 10 }, "lastName": { "type": ["string", "null"], "description": "Name of the person.", "example": { "value": "John" }, "minLength": 1, "maxLength": 10 }, "id": { "description": "Unique identifer", "example": "5e91507e-5630-4efd-9fd4-799178870b10", "format": "uuid", "type": "string" } }, "required": ["id"], "type": "object" } } } }, "401": { "description": "Failed to retrieve user!", "content": { "application/json": { "schema": { "properties": { "message": { "readOnly": true, "type": "string" } }, "type": "object" } } } } } } } } } ``` ## Schemas ### Primitive Data types All schemas are reflective of the latest [Json Schema](https://json-schema.org/understanding-json-schema/reference). - [number](#defining-a-number) - [integer](#defining-a-integer) - [string](#defining-a-string) - [boolean](#defining-a-boolean) #### Number ```ts Number.addDescription("I am a OpenAPI Number!") .addFormat("double") .addDefault(1) .addMinimum(0.5) .addMaximum(2.5) .addExclusiveMin(1); ``` ```json { "type": "number", "description": "I am a OpenAPI Number!", "default": 1.5, "minimum": 0.5, "maximum": 2.5, "exclusiveMinimum": true, "format": "double" } ``` #### Integer ```ts Integer.addDescription("I am a OpenAPI Number!") .addFormat("int32") .addDefault(1) .addMinimum(0.5) .addMaximum(2.5) .addExclusiveMin(1); ``` #### Defining a String ```ts String.addDescription("I am an OpenApi String!") .addDefault("OAS!") .addMinLength(1) .addMaxLength(4) .addPattern(/something/); ``` #### Defining a Boolean ```ts Boolean.addDescription("I am a OpenAPI boolean!") .addDefault(false) .addExample(true); ``` ### Objects Declare properties and other metadata on OpenAPI `Object` with the `addProperties` method. ```ts Object.addProperties({ firstName: String, lastName: String, id: String, }); ``` ### Arrays Arrays can be typed with other schema types, see below for an example of a string array. ```ts Array.addItems(String) .addMinItems(1) .addMaxItems(10) .addDefault(["defaultVal"]); ```