Skip to content

An npm package for offering semi-auto generated api documentation like Swagger for Express and integrating with Keycloak SSO protected endpoints.

License

Notifications You must be signed in to change notification settings

bcgov/citz-imb-kc-express-api-docs

Repository files navigation

BCGov Express + SSO Keycloak API Documentation

Lifecycle:Experimental License

NPM NodeJS Typescript Express

Backlog:

  • Make generateDocs work with Vanilla vs TypeScript and Development vs Production
  • Add support for body
  • Get and display responses
  • Clean up login button state
  • Add entities
  • Add minimize all button for modules
  • Describe syntax and structure requirements/limitations in README
  • Expand login to more than just IDIR
  • Check for protectedRoute on router routes
  • Check for describe in zod schema to add to params

TL/DR

  1. Install package by following the steps at Installing the Package.
  2. Set up the package by following the steps at Basic Setup Guide.
  3. Use with @bcgov/citz-imb-kc-express.
  4. Allows automatic generation of api documentation and integration with Keycloak SSO protected endpoints.

Table of Contents

General Information

  • For running on a NodeJS:20 Express API.
  • Works with Vanilla JavaScript or Typescript 5.
  • Use with @bcgov/citz-imb-kc-express.
  • Allows automatic generation of api documentation and integration with Keycloak SSO protected endpoints.

Example:

Example Screenshot of API Docs



Installing the Package

  1. Add the following line to your package.json:
{
  "dependencies": {
    "@bcgov/citz-imb-kc-express-api-docs": "https://github.com/bcgov/citz-imb-kc-express-api-docs/releases/download/v<VERSION>/bcgov-citz-imb-kc-express-api-docs-<VERSION>.tgz",
    // The rest of your dependencies...
  },
}
  1. Replace <VERSION> with the version you wish to use. Reference releases for version numbers.

  1. Run npm install to add the package.

Return to Top


Basic Setup Guide

Requirements:

  • Endpoints must be organized by module (by default this means a src/modules directory).
  • Modules must be defined as a base route in express file such as health module as app.use('/health', router);
  • Each module must have a single router.ts file (controllers can be in separate files).
  • Use of module type imports instead of commonjs type require.
  • Schemas used in getParams, getQuery, and getBody must be imported to controller files from another file.
  • Controller functions must have a description in the form of a single or multi-line comment above them. For multi-line comments, the first line of text will be taken as the description.
  1. Add import const { apiDocs } = require('@bcgov/citz-imb-kc-express-api-docs'); or import { apiDocs } from '@bcgov/citz-imb-kc-express-api-docs'; to the top of the file that defines the express app. Add apiDocs(app, API_DOCS_CONFIG); below the definition of the express app, where app is defined by express().

Note the default config options:

// Automatically set, unless changed
const DefaultAPIDocsConfig = {
  title: "API Documentation",
  expressFilePath: "src/express.ts",
  modulesBasePath: "src/modules",
  modules: {},
};

Example:

import express from 'express';
import { apiDocs } from '@bcgov/citz-imb-kc-express-api-docs';

const API_DOCS_CONFIG = {
  modules: {
    health: {
      description: 'Check application health.',
    },
  },
  customSchemas: { // This is an optional property.
    'zodProperty.nonEmptyString': { // Example of custom zod schema object.
      required: true,
      type: 'string',
    },
  },
  customControllers: {  // This is an optional property.
    'dataController.getAllItems': {
      description: 'Returns all items.',
      // optional add query property (see TypeScript types).
    },
  },
  customResponseStatuses: { // This is an optional property.
    'statusCode.OK': 200,
    'statusCode.CREATED': 201,
    'statusCode.ACCEPTED': 202,
    'statusCode.NO_CONTENT': 204,
    'statusCode.NOT_MODIFIED': 304,
    'statusCode.BAD_REQUEST': 400,
    'statusCode.UNAUTHORIZED': 401,
    'statusCode.FORBIDDEN': 403,
    'statusCode.NOT_FOUND': 404,
    'statusCode.IM_A_TEAPOT': 418,
    'statusCode.INTERNAL_SERVER_ERROR': 500,
    'statusCode.NOT_IMPLEMENTED': 501,
    'statusCode.SERVICE_UNAVAIBLABLE': 503,
  },
  defaultResponses: [500], // This is an optional property.
};

// Define Express App
const app = express();

// Initialize api docs
apiDocs(app, API_DOCS_CONFIG);
  1. Add the required environment variables from the Environment Variables section below.

Return to Top


Environment Variables

# Ensure the following environment variables are defined on the container.

BACKEND_URL= # URL of the backend application.

SSO_CLIENT_ID= # Keycloak client_id
SSO_CLIENT_SECRET= # Keycloak client_secret
SSO_AUTH_SERVER_URL= # Keycloak auth URL, see example below.
# https://dev.loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect

DEBUG= # (optional) Set to 'true' to get useful debug statements in api console.
VERBOSE_DEBUG= # (optional) Set to 'true' to get extra details from DEBUG.

Return to Top


Directory Structure

.
├── .github/
|   ├── config/
|   |   └── dep-report.json5                # Configure options for NPM Dep Report.
|   ├── helpers/
|   |   ├── github-api/                     # Functions to access the GitHub API.
|   |   ├── create-npm-dep-report-issues.js # Creates GitHub Issues for Npm Dep Reports.
|   |   ├── create-npm-dep-report.js        # Creates text bodies for Npm Dep Reports.
|   |   ├── parse-json5-config.js           # Parses json5 files for GitHub actions output.
|   |   └── parse-npm-deps.js               # Parses package.json files for changes to package versions.
|   ├── workflows/
|   |   ├── npm-dep-report.yaml             # Reports on new package versions.
|   |   └── releases.yaml                   # Creates a new GitHub Release.
├── .husky/
|   └── post-commit                         # Script that runs after a git commit.
├── scripts/
|   ├── bump-version.mjs                    # Bumps version in package.json file.
|   ├── post-commit-version-change.mjs      # Bumps version when post-commit is run.
|   ├── remove-dts-files.mjs                # Removes TypeScript declaration files from the build.
|   └── remove-empty-dirs.mjs               # Removes empty directories from the build.
├── src/                                    # Source code for package.
|   ├── static/                             # Static files served as the api documentation.
|   ├── utils/                              # Utility functions.
|   ├── config.ts                           # Config variables.
|   ├── index.ts                            # Export functions for the package.
|   └── types.ts                            # TypeScript types.
├── package.json                            # Package config and dependencies.
├── .npmrc                                  # NPM config.
├── rollup.config.mjs                       # Builds and compiles TypeScript files into JavaScript.
├── rollupdts.config.mjs                    # Builds and compiles TypeScript declartion files.

Return to Top


Scripts

# Compile all src code into a bundle in build/ directory.
$ npm run build
# Part of 'build' and it bundles the typescipt declarations into a single bundle.d.ts file.
$ npm run build:dts
# Part of build and it removes directories and files before the build.
$ npm run clean:prebuild
# Part of build and it removes directories and files after the build.
$ npm run clean:postbuild
# Used to package the code before a release.
$ npm run pack

Return to Top


Module Exports

These are the functions and types exported by the @bcgov/citz-imb-kc-express-api-docs module.

import {
  apiDocs, // Initialization function to generate api docs.
} from '@bcgov/citz-imb-kc-express-api-docs';

// TypeScript Types:
import {
  Config, // Type for configuration options.
} from '@bcgov/citz-imb-kc-express';

Return to Top


TypeScript Types

These are the TypeScript types of the @bcgov/citz-imb-kc-express-api-docs module.

const apiDocs: (app: Application, config: Config) => void;

type CustomSchemaConfig = {
    [pattern: string]: ParamProperties;
};
type CustomControllerConfig = {
  [controller: string]: {
    description: string;
    query?: {
      [param: string]: ParamProperties;
    };
  };
};
type CustomResponseStatuses = {
  [variable: string]: number;
};
type Config = {
  title: string;
  expressFilePath: string;
  modulesBasePath: string;
  modules: {
    [module: string]: {
      description: string;
    };
  };
  customSchemas?: CustomSchemaConfig;
  customControllers?: CustomControllerConfig;
  customResponseStatuses?: CustomResponseStatuses;
  defaultResponses?: number[];
};
type Method = "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
type ParamProperties = {
    required: boolean;
    type: string; // "string" | "number" | "boolean"
    description?: string;
};
type Endpoint = {
    route: string;
    method: Method;
    description?: string;
    controller: {
        name: string;
        path: string;
        query?: {
            [param: string]: ParamProperties;
        };
        pathParams?: {
          [param: string]: ParamProperties;
        };
    };
    responseStatusCodes?: number[];
};
type Modules = {
    [key: string]: {
        description: string;
        protected: boolean;
        protectedBy: string[];
        protectedByAll: boolean;
        endpoints: Endpoint[];
    };
};

Return to Top


Applications using this Solution

The following applications are currently using this keycloak implementation solution:

PLAY - CITZ IMB Package Testing App

Return to Top

About

An npm package for offering semi-auto generated api documentation like Swagger for Express and integrating with Keycloak SSO protected endpoints.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published