OpenAPI
OpenAPI endpoints are created by setting up an <openapi />
webrule.
Setup
To add a new endpoint:
- Create an
openapi.yml
specifying your API - Setup a TS or JS file to implement the endpoints
- Use
x-webhare-authorization
to point to a function taking care of authorization. - Use
x-webhare-implementation
to point to a function actually implementing the operation. - Add an
<openapiservice name=… spec=… />
to the backendservices. - Add an
<openapi path=… service=… />
at any point where you would otherwise add a<webrule />
- Setup multiple versions by using multiple
<openapi
rules with different paths. Versions are otherwise completely independent
- Setup multiple versions by using multiple
Setting up an authorization callback is required to prevent a typo/parsing error from removing all security on your API.
The authorization callback can be defined at the toplevel or at any path or operation level - the most specific handler will be used.
If no callback is set up, all API calls will return a 403 Forbidden
error.
An operation without an implementation function will still validate parameters and authorization but return a 501 Not implemented
when
otherwise properly invoked.
Authorization functions should have the following signature: export async function auth(req: RestRequest): Promise<RestAuthorizationResult>
Implementation functions should have the following signature: export async function impl(req: RestRequest): Promise<WebReponse>
After setting up the above rules you should be able to access the 'openapi.json' document below the specified API path. Eg if you defined your API as follows:
<moduledefinition>
<services>
<openapiservice name="myapp" spec="openapi/myapp/myapp.yml" />
…
<backend>
<openapi path="root:myapp/1/" service="myapp" />
You should be able to see your API on https://my.webhare.dev/myapp/1/openapi/openapi.json. Both this file and a Swagger-UI are linked by default from the root of your API (eg https://my.webhare.dev/myapp/1/)
Examples
A minimal openapi.yml file:
---
openapi: 3.0.2
info:
title: My API
version: 1.0.0
x-webhare-authorization: openapi.ts#needSecret
servers:
- url: "."
description: API Server
paths:
"/dummy":
get:
responses:
"200":
description: A dummy
x-webhare-implementation: openapi.ts#getDummy
The accompanying openapi.ts
file:
import { createJSONResponse, RestAuthorizationResult, RestRequest } from "@webhare/router";
export async function needSecret(req: RestRequest): Promise<RestAuthorizationResult> {
return {
authorization: { user: "secret" },
authorized: req.webRequest.headers.get("authorization") === "bearer secret"
};
}
export async function getDummy(req: RestRequest) {
return createJSONResponse(200, { answer: 42 });
}