FORGEBOX Enterprise 🚀 - Take your ColdFusion (CFML) Development to Modern Times! Learn More...

Preside Extension: Swagger Support for REST APIs

v1.0.10 Public

PresideCMS Extension: Swagger Support for REST APIs

This is an extension for Preside that generates a Swagger specification and provides an API dashboard for the in-built REST architecture. For details on the REST framework implementation see here: Preside REST Framework Documentation

Configuration

The extension provides a system configuration screen that allows you to configure:

  • Title: the title of the API, is generated by default based on either the Preside Application ID or Site name (required)
  • Version: the version of the API, defaults to 0.1.0 (required)
  • Description: a brief description of what the API does (optional)
  • Terms of service: e.g. a URL to the Terms of service (optional)
  • Contact Name: a Support contact name (optional)
  • Contact URL: a Support contact URL (optional)
  • Contact Email: a Support contact Email (optional)
  • Host name: the host name to be included in the spec and used in the Swagger UI (should include the port if necessary, if not set the system tries to detect it)
  • Secure (https): whether the API is secured via https (defaults to http)

Make sure that the hostname and whether to use HTTPS or not is set correctly. Otherwise the Swagger UI will not work.

Usage

Two new handlers are available that are publicly accessible:

  • http://servername:serverport/swagger (this returns the generated Swagger 2.0 Specification in JSON format)
  • http://servername:serverport/swagger/ui (this displays the Swagger UI preloaded with the REST API Spec)

In addition a new admin sidebar menu item named Swagger is available with quicklinks and an integrated UI Dashboard.

API Endpoint Annotations

The Specification is generated based on component metadata from RESTful handlers. Have a look here how to create REST API Endpoints in Preside.

The following attributes (Standard CF as well as custom ones) are evaluated:

cfcomponent

  • restUri: the relative REST Endpoint Path (this is part of the general Preside REST API Concept)

cffunction

  • hint: will be used as endpoint description
  • restVerb: this is optional, otherwise the method name is used as verb (this is part of the general Preside REST API Concept)
  • swagger_tags: can be used to group endpoints logically
  • swagger_summary: a short summary description of what the endpoint does
  • swagger_responses: define several possible responses here - see below for details

Swagger Responses in more detail:

You are able to define multiple responses for a single endpoint by using the custom cffunction attribute swagger_responses like this:

// using a semicolon as the delimiter
RESPONSE_1;RESPONSE_2;RESPONSE_3

A single response has the following format:

// use a colon as the delimiter
CODE:DESCRIPTION: HEADERS
  • CODE: the http status code
  • DESCRIPTION: the response text (optional, default="default")
  • HEADERS: a list of headers that are returned (optional, comma-delimited)

The following are all valid examples that could be used:

200:pet created:X-NEW-ID;400:pet already existing

200:pet collection

200;404:pet not found

cfargument

  • name: the parameter name
  • required: whether it's a required argument, all uri tokens are required by default (optional)
  • default: a default value that is set (optional)
  • hint: the parameter description (optional)
  • swagger_type: custom swagger type to be used - see below for default mappings (optional)
  • swagger_format: custom swagger format to be used - see below for defaults (optional)

It is automatically determined whether a given argument is part of the request uri - a token. For all other arguments the evaluation follows some rules:

  • if it's a get request, the parameters are treated as query parameters
  • if it's not a get request, the parameters are treated as form data
  • default type to be used is string

Mappings

The following CFML > Swagger Mappings are used:

  • boolean > boolean
  • string > string
  • numeric > number
  • date > string
  • uuid > string
  • any > string

In case no custom swagger format is defined for some types specific default formats are used:

  • number > float
  • integer > int32
  • date > date-time

The following valid swagger types are supported (via swagger_type annotation on cfargument):

  • integer
  • string
  • number
  • boolean

The following valid swagger formats can be used in combination with a valid swagger type (via swagger_format annotation on cfargument):

  • integer: int32, int64
  • number: float, double
  • string: byte, binary, date, date-time, password

Example

The following shows a full example of how a RESTful API Handler could look like:

/**
 * @restUri /pets/{id}/
 */
component {

    property name="petDao" inject="presidecms:object: pet";

    /**
     * @hint This endpoint returns a single pet
     * @swagger_tags pets
     * @swagger_summary return a pet
     * @swagger_responses 200:single pet;404:pet not found
     * @id.hint the object id of the pet object
     */
    private void function get(required uuid id) {

        var result = petDao.selectData(id=arguments.id);

        if (result.recordCount eq 0) {
            restResponse.noData().setStatus(404);
            return;
        }
        
        restResponse.setData(queryRowData(result, 1));
    }

    /**
     * @hint This endpoint updates a pet
     * @swagger_tags pets
     * @swagger_summary update a pet
     * @swagger_responses 200:pet updated
     * @id.hint the object id of the pet object
     * @name.hint the name of the pet
     */
    private void function put(required uuid id, required string name) {

        petDao.updateData(
            id=arguments.id,
            data={
                name=arguments.name
            }
        );

        restResponse.noData();
    }

    /**
     * @hint This endpoint is used to delete a pet
     * @swagger_tags pets
     * @swagger_summary delete a pet
     * @swagger_responses 200:pet deleted
     * @id.hint the object id of the pet object
     */
    private void function delete(required uuid id) {

        petDao.deleteData(id=arguments.id);

        restResponse.noData();
    }
}

Installation

Install the extension to your application via either of the methods detailed below (Git submodule / CommandBox) and then enable the extension by opening up the Preside developer console and entering:

extension enable preside-ext-rest-swagger
reload all

Git Submodule method

From the root of your application, type the following command:

git submodule add https://bitbucket.org/hwsdev/preside-ext-rest-swagger.git application/extensions/preside-ext-rest-swagger

CommandBox (box.json) method

From the root of your application, type the following command:

box install preside-ext-rest-swagger

Credits

This Extensions makes use of the Swagger UI code which can be found here: https://github.com/swagger-api/swagger-ui

Ideas for the future

  • support for detailed response models
  • deal with different security stuff (authentication, etc.)
  • custom design for the Swagger UI dashboard
  • no need to display the spec URL in the Swagger UI as it's fixed anyway
  • create a separate generated documentation beside the Swagger UI dashboard
  • possibility to disable the UI Dashboard via a system setting
  • define custom parameter types (path, query, etc.)

Here are all the versions for this package. Please note that you can leverage CommandBox package versioning to install any package you like. Please refer to our managing package version guide for more information.

Version Created Last Update Published By Stable Actions
Current
1.0.10 Jul 18 2017 07:38 AM Jul 18 2017 07:38 AM
Version History
1.0.9 May 16 2017 09:48 AM May 16 2017 09:48 AM
1.0.8 May 02 2017 01:16 PM May 02 2017 01:16 PM
1.0.7 Oct 18 2016 11:11 AM Oct 18 2016 11:11 AM
1.0.6 Oct 16 2016 01:12 PM Oct 16 2016 01:12 PM
1.0.5 Oct 14 2016 10:29 AM Oct 14 2016 10:29 AM
1.0.4 Oct 14 2016 09:08 AM Oct 14 2016 09:08 AM
1.0.3 Oct 11 2016 01:43 PM Oct 11 2016 01:43 PM
1.0.2 Oct 11 2016 02:26 AM Oct 11 2016 02:26 AM
1.0.1 Sep 30 2016 05:00 AM Sep 30 2016 05:00 AM
1.0.0 Sep 29 2016 12:17 PM Sep 29 2016 12:17 PM

 

No collaborators yet.
     
  • Sep 29 2016 12:17 PM
  • Jul 18 2017 07:38 AM
  • 870
  • 2299
  • 1058