1.0.1 • Published 6 months ago

rest-openapi v1.0.1

Weekly downloads
-
License
-
Repository
-
Last release
6 months ago

rest-openapi

Summary

This framework allows to generate typescript types based on json schema definitions and apply validation for input/output object in REST endpoints.

Source of truth is src/types/schemas/*.yml files for types definitions. types/schemas directory can be located at any level under src.

Generation of files in types/.json-schema is needed for types generation only._

Code structure of project which uses this library

  • src/openapi.yml - API definition
  • src/types/schema - directory for yml types definitions using JSON Schema format
  • src/types/definition - directory generated typescript types from yml definitions
  • src/json-schema-map-generated.json - generated json file with mapping of types and their json schema

Error types

There are predefined JSON schema definitions and exceptions for the following errors

  • ApiValidationError - ApiValidationException (status 400)
  • ApiInternalServerError - ApiInternalServerErrorException (status 500)
  • ApiNotFoundError - ApiNotFoundException (status 404)
  • ApiProcessingError - ApiProcessingException (status 422)
  • ApiAuthenticationFailedError - ApiAuthenticationFailedException (status 401)

ApiValidationError and ApiValidationException are thrown and handled by middleware.

ApiInternalServerError/ApiInternalServerErrorException - any unknown error will be converted to ApiInternalServerError by middleware and returned as response.

ApiNotFoundException, ApiProcessingException and ApiAuthenticationFailedException can be throws by application and will be converted by middleware to corresponding response.

Referencing error schemas in OpenApi schema

Just add the following lines in openaapi.yml file

components:
  schemas:
    ApiValidationError:
      $ref: '../node_modules/rest-openapi/src/types/schemas/api-validation-error.yml'
    ApiInternalServerError:
      $ref: '../node_modules/rest-openapi/src/types/schemas/api-internal-server-error.yml'
    ApiProcessingError:
      $ref: '../node_modules/rest-openapi/src/types/schemas/api-processing-error.yml'
    ApiNotFoundError:
      $ref: '../node_modules/rest-openapi/src/types/schemas/api-not-found-error.yml'
    AuthenticationFailedError:
      $ref: '../node_modules/rest-openapi/src/types/schemas/api-authentication-failed-error.yml'
  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiValidationError'
    ServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiInternalServerError'
    ProcessingError:
      description: Processing error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiProcessingError'
    NotFound:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiNotFoundError' 
    AuthenticationFailed:
      description: Authentication failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthenticationFailedError'

And then use them in endpoints response

      responses:
        '400':
          $ref: '#/components/responses/BadRequest'
        '422':
          $ref: '#/components/responses/ProcessingError'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'

Adding type or change existing

Create new yml type or change existing in src/types/schemas

title: Pet
required:
  - name
properties:
  id:
    type: integer
    example: 10
  name:
    type: string
    example: doggie
  category:
    $ref: 'category.yml'
  tags:
    type: array
    items:
      $ref: 'tag.yml'
  status:
    $ref: 'pet-status.yml'
type: object
additionalProperties: false

Run types generation

npm run build
npm run generate-types 
npm run build

Then commit changed/new .yml and .d.ts files.

Defining type for input query parameters

All query parameters should be defined in file types/schemas/query-parameter.yml on any level.

parameters:
  LimitParam:
    name: limit
    in: query
    description: Maximum number of items to return
    required: false
    schema:
      type: integer
      default: 10

  ExclusiveStartKeyParam:
    name: exclusiveStartKey
    in: query
    description: The primary key of the first item that this operation will evaluate
    required: false
    schema:
      type: string

Then they should be imported in openapi.yml under components/parameters section

components:
  parameters:
    LimitParam:
      $ref: 'types/schemas/query-parameters.yml#/parameters/LimitParam'
    ExclusiveStartKeyParam:
      $ref: 'types/schemas/query-parameters.yml#/parameters/ExclusiveStartKeyParam'

And then they can be used in endpoint configuration

      parameters:
        - $ref: '#/components/parameters/LimitParam'
        - $ref: '#/components/parameters/ExclusiveStartKeyParam'

For validation with AJV type schema in directory types/schemas should be defined. File name should end with query-params and typename should end with QueryParams. Typename prefix should be set to openapi operationId. It is needed for validation purposes during compilation.

title: FindPetsByStatusQueryParams
properties:
  limit:
    $ref: '../../../../types/schemas/query-parameters.yml#/parameters/LimitParam/schema'
  exclusiveStartKey:
    $ref: '../../../../types/schemas/query-parameters.yml#/parameters/ExclusiveStartKeyParam/schema'
  status:
    $ref: './query-parameters.yml#/parameters/PetStatusParam/schema'
type: object
additionalProperties: false

Then to initiate query parameters check type name should be added to middleware.

const findPetsByStatusHandler = restOpenapiCompoundMiddleware(lambdaHandler, {
    inputTypeName: null,
    inputQueryParamsTypeName: 'FindPetsByStatusQueryParams',
    outputTypeName: 'FindPetsByStatusOutput'
});

If validation is OK, then query parameters will be parsed to object and passed in context.inputQueryParams.

Run docker for swagger

docker run -d -p 8080:8080 --platform linux/amd64 swaggerapi/swagger-editor

Deploying to code artifacts

login to repo

aws codeartifact login --tool npm --repository rest-openapi --domain rest-openapi --domain-owner 962397990111 --region us-east-1 --namespace @rest-openapi

or

AUTH_TOKEN=$(aws codeartifact get-authorization-token --domain rest-openapi --domain-owner 962397990111 --query authorizationToken --output text)
npm config set //rest-openapi-962397990111.d.codeartifact.us-east-1.amazonaws.com/npm/rest-openapi/:_authToken ${AUTH_TOKEN}
npm install node@18.17.0
npm install  npm@10.2.4


nvm install v18.17.0
nvm use

https://itnext.io/exploring-an-openapi-swagger-first-approach-to-serverless-development-on-aws-d19f0e9ca257

https://ajv.js.org/guide/typescript.html

generation of axios client

npx openapicmd typegen ./openapi.yml > openapi.d.ts

https://openapistack.co/docs/openapicmd/typegen/
1.0.1

6 months ago

1.0.0

6 months ago