You are on page 1of 9

1

API Catalog Automatically Detecting Documentation


Errors
Building a library of web services is only worthwhile if you have a way to find those services. Like any library, a web service library needs a
catalog. We build our catalog with a tool that scans our web services code and produces a set of JSON objects that describe the available
services. These JSON objects, in turn, can then be displayed in a user interface that presents them as a catalog of services.
This level of automation represents a real step forward, but we need to go a little further. We need to add a component to the process that will
automatically analyze the catalog data and looking for gaps, services that developers may have neglected to document either in whole or in part.
Building and plugging in that component is what we need you to do.
As you proceed, lets make a point to meet briefly (15 minutes or so) each morning to review progress, issues and questions.
Step 1 Read the background documentation on the tool
http://dstconnect.dstcorp.net/display/ALLOY/USIRKS+API+Catalog
Read the above page, take a look at the linked catalog, and peruse the linked documentation on the Swagger specification. Jot down questions
and observations, and we can cover them in our morning standups.
Step 2 Set up the Business Services Library (BSL)
http://dstconnect.dstcorp.net/display/ALLOY/BSL+Developer+Setup
The link above describes how to set up the Business Services Library (our framework for building web services). Youll just need to run the library
import script described on the above page and the component script to import the AssetMgmtServices component (hint: component is the
term we use to describe a project that has a bundle of related web services in it).
Before you get started, be sure to check the prerequisites below. If youre missing any, we can chat about the best way to satisfy them.
Prerequisites:
Git ID and SCM Git Install
2

Basic knowledge of Git (enough to run a script to clone a workspace)
Basic knowledge of Spring and Spring MVC (we have video training courses for this)
Basic knowledge of Maven
STS (Spring-optimized version of Eclipse)
If you were going to develop web services, I would suggest you go through full training on the BSL. But your real focus is on the tool, and I can
give you enough background on the BSL for your task in under half an hour, once you have the code on your machine.
Step 3 Get the documentation tool running on your machine
As the catalog page notes, the documentation tool is a Java doclet: BusinessServicesDoclet. You can retrieve it using the bsl_component script
from the BSL set up page. After cloning the repository, just import it into your workspace as you would any Java project. The catalog
documentation page describes how to run the tool. Your goal on this step is to get the tool running and producing documentation that displays
through your local web server (see Prerequisite below).
Prerequisite:
Apache httpd 2.2 (web server) contact me for a configuration file once you have this set up
Step 4 Review the documentation tool process and data
From a process perspective, the doclet proceeds in three main steps: parsing the code and comments to build structured objects with the API
documentation, organizing the raw documentation and rendering the documentation into distinct JSON files. Your validation process will not
need to worry about the code scan. Instead it will be dealing with the structured objects that contain the API documentation after they have
been organized.
The documentation is broken into two main groups: APIs (information about the service operations) and Models (the request data sent to
service and response data received from services). After the organization step, the APIs and the models related to them are grouped into
ApiDeclaration objects, the complete collection of which is held by the ParsedResources object.
3



class businessservices
parse::ParsedResources
- l ogger: Logger = LoggerFactory ... {readOnl y}
- model s: Map<Stri ng, Model > = new HashMap<Str...
- opti ons: Servi cesDocl etOpti ons
- resourceLi sti ng: ResourceLi sti ng
- resourcePathMap: Map<Stri ng, Api Decl arati on> = new HashMap<Str...
+ addModel s(Li st<Model >) : voi d
+ addResource(Stri ng) : Api Decl arati on
+ bui l dResourceLi sti ng() : ResourceLi sti ng
+ di stri buteModel s() : voi d
- fi ndRequestModel s(Api Decl arati on, Operati on) : voi d
+ fi ndResource(Stri ng) : Api Decl arati on
- fi ndResponseModel s(Api Decl arati on, Operati on) : voi d
- getModel Dependenci es(Stri ng) : Map<Stri ng, Model >
+ getModel s() : Map<Stri ng, Model >
+ getOpti ons() : Servi cesDocl etOpti ons
+ getResourceLi sti ng() : ResourceLi sti ng
+ getResourcePathMap() : Map<Stri ng, Api Decl arati on>
- popul ateParameterFromRequestModel (Parameter, Map<Stri ng, Model >) : voi d
+ setModel s(Map<Stri ng, Model >) : voi d
+ setOpti ons(Servi cesDocl etOpti ons) : voi d
+ setResourceLi sti ng(ResourceLi sti ng) : voi d
+ setResourcePathMap(Map<Stri ng, Api Decl arati on>) : voi d
model::ApiDeclaration
- api Map: Map<Stri ng, Api > = new HashMap<Str...
- api s: Li st<Api >
- api Versi on: Stri ng
- basePath: Stri ng
- descri pti on: Stri ng
- l ogger: Logger = LoggerFactory.g... {readOnl y}
- model s: Map<Stri ng, Model > = new HashMap<Str...
- resourcePath: Stri ng
- swaggerVersi on: Stri ng
+ fi ndApi (Stri ng) : Api
+ getApi Map() : Map<Stri ng, Api >
+ getApi s() : Li st<Api >
+ getApi Versi on() : Stri ng
+ getBasePath() : Stri ng
+ getDescri pti on() : Stri ng
+ getModel s() : Map<Stri ng, Model >
+ getResourcePath() : Stri ng
+ getSwaggerVersi on() : Stri ng
+ setApi s(Li st<Api >) : voi d
+ setApi Versi on(Stri ng) : voi d
+ setBasePath(Stri ng) : voi d
+ setDescri pti on(Stri ng) : voi d
+ setModel s(Map<Stri ng, Model >) : voi d
+ setResourcePath(Stri ng) : voi d
+ setSwaggerVersi on(Stri ng) : voi d
model::Api
- descri pti on: Stri ng = ""
- operati ons: Li st<Operati on> = new ArrayLi st<O...
- path: Stri ng = ""
+ getDescri pti on() : Stri ng
+ getOperati ons() : Li st<Operati on>
+ getPath() : Stri ng
+ setDescri pti on(Stri ng) : voi d
+ setOperati ons(Li st<Operati on>) : voi d
+ setPath(Stri ng) : voi d
model::Model
- descri pti on: Stri ng
- i d: Stri ng
- i sAl i ased: bool ean = fal se
- properti es: Map<Stri ng, Model Property> = new HashMap<Str...
- requi red: Li st<Stri ng>
+ getDescri pti on() : Stri ng
+ getId() : Stri ng
+ getProperti es() : Map<Stri ng, Model Property>
+ getRequi red() : Li st<Stri ng>
+ i sAl i ased() : bool ean
+ setAl i ased(bool ean) : voi d
+ setDescri pti on(Stri ng) : voi d
+ setId(Stri ng) : voi d
+ setProperti es(Map<Stri ng, Model Property>) : voi d
+ setRequi red(Li st<Stri ng>) : voi d
*
1
*
1
*
1
4

A closer look at the API object:


class API
model::Api
- descri pti on: Stri ng = ""
- operati ons: Li st<Operati on> = new ArrayLi st<O...
- path: Stri ng = ""
+ getDescri pti on() : Stri ng
+ getOperati ons() : Li st<Operati on>
+ getPath() : Stri ng
+ setDescri pti on(Stri ng) : voi d
+ setOperati ons(Li st<Operati on>) : voi d
+ setPath(Stri ng) : voi d
model::Operation
- dataAccessComponents: Li st<Stri ng> = new ArrayLi st<S...
- dstServi ceRequest: Stri ng
- method: Stri ng = ""
- ni ckname: Stri ng = ""
- notes: Stri ng
- operati onType: Stri ng = ""
- parameters: Li st<Parameter> = new ArrayLi st<P...
- responseMessages: Li st<ResponseMessage> = new ArrayLi st<R...
- summary: Stri ng = ""
+ getDataAccessComponents() : Li st<Stri ng>
+ getDstServi ceRequest() : Stri ng
+ getMethod() : Stri ng
+ getNi ckname() : Stri ng
+ getNotes() : Stri ng
+ getOperati onType() : Stri ng
+ getParameters() : Li st<Parameter>
+ getResponseMessages() : Li st<ResponseMessage>
+ getSummary() : Stri ng
+ setDataAccessComponents(Li st<Stri ng>) : voi d
+ setDstServi ceRequest(Stri ng) : voi d
+ setMethod(Stri ng) : voi d
+ setNi ckname(Stri ng) : voi d
+ setNotes(Stri ng) : voi d
+ setOperati onType(Stri ng) : voi d
+ setParameters(Li st<Parameter>) : voi d
+ setResponseMessages(Li st<ResponseMessage>) : voi d
+ setSummary(Stri ng) : voi d
model::Parameter
- dataType: Stri ng = ""
- descri pti on: Stri ng = ""
- format: Stri ng = ""
- name: Stri ng = ""
- paramType: Stri ng = ""
- requi red: bool ean
+ getDataType() : Stri ng
+ getDescri pti on() : Stri ng
+ getFormat() : Stri ng
+ getName() : Stri ng
+ getParamType() : Stri ng
+ i sRequi red() : bool ean
+ setDataType(Stri ng) : voi d
+ setDescri pti on(Stri ng) : voi d
+ setFormat(Stri ng) : voi d
+ setName(Stri ng) : voi d
+ setParamType(Stri ng) : voi d
+ setRequi red(bool ean) : voi d
*
1
* 1
5

A closer look at Models:

class Models
model::Model
- descri pti on: Stri ng
- i d: Stri ng
- i sAl i ased: bool ean = fal se
- properti es: Map<Stri ng, Model Property> = new HashMap<Str...
- requi red: Li st<Stri ng>
+ getDescri pti on() : Stri ng
+ getId() : Stri ng
+ getProperti es() : Map<Stri ng, Model Property>
+ getRequi red() : Li st<Stri ng>
+ i sAl i ased() : bool ean
+ setAl i ased(bool ean) : voi d
+ setDescri pti on(Stri ng) : voi d
+ setId(Stri ng) : voi d
+ setProperti es(Map<Stri ng, Model Property>) : voi d
+ setRequi red(Li st<Stri ng>) : voi d
model::ModelProperty
- descri pti on: Stri ng
- format: Stri ng
- i tems: Model Property
- name: Stri ng
- propertyType: Stri ng
- ref: Stri ng
+ getDescri pti on() : Stri ng
+ getFormat() : Stri ng
+ getItems() : Model Property
+ getName() : Stri ng
+ getPropertyType() : Stri ng
+ getRef() : Stri ng
+ setDescri pti on(Stri ng) : voi d
+ setFormat(Stri ng) : voi d
+ setItems(Model Property) : voi d
+ setName(Stri ng) : voi d
+ setPropertyType(Stri ng) : voi d
+ setRef(Stri ng) : voi d
* 1
6

Step 5 Review the error conditions
Here are the error conditions that you will be checking for:
Level Violation Locator Field Notes
Api.Operation The operation has not been
classified into a resource
group.
Api.path :
Operation.method :
Operation.nickname
If ApiDeclaration.resourcePath
is /uncategorized or blank
This will be reported for all
operations within all Apis in an
/uncategorized
ApiDeclaration. Thats the
default grouping the parser
applies to any services without
a resource group assigned.
Api.Operation The operation lacks a
request model.
Api.path :
Operation.method :
Operation.nickname
If Operation.dstServiceRequest
is blank

Api.Operation The operations request
model cannot be found in
the documentation.
Api.path :
Operation.method :
Operation.nickname
If Operation.dstServiceRequest
(non-blank) cannot be found in
the ApiDeclaration model map
(ApiDeclaration.models)

Api.Operation The operation lacks a
response model
Api.path :
Operation.method :
Operation.nickname
If Operation.type is blank
Api.Operation The operations response
model cannot be found in
the documentation.
Api.path :
Operation.method :
Operation.nickname
If Operation.type (non-blank)
cannot be found in the
ApiDeclaration model map
(ApiDeclaration.models)

Api.Operation The operation has no
summary description.
Api.path :
Operation.method :
Operation.nickname
If Operation.summary is blank
Api.Operation The parameter has no type. Api.path :
Operation.method :
Operation.nickname :
Parameter.name
If Parameter.paramType is
blank

Model.Property The model property has no Model.property.description If Model.Property.description
7

description. is blank

Step 6 Review the error format
Ultimately, we want the errors to be output to file. Weve played with a few different ideas in that regard, but as a practical matter have settled
on simple XML. We see two files, one for operation errors and the other for model errors.

8

Operations









Models







Step 7 Propose a design

<?xml version="1.0" encoding="UTF-8"?>
<documentationErrors>
<documentationError>
<type>Operation</type>
<code>OP001</code>
<message>The operation has not been classified into a resource group</message>
<component>ServiceProvidersController.getServiceProviders</component>
<path>/fund-sponsors/{fundSponsorId}/funds/{fundCode}/service-providers</path>
<method>GET</method>
<parameter></parameter>
</documentationError>
</documentationErrors>
<?xml version="1.0" encoding="UTF-8"?>
<documentationErrors>
<documentationError>
<type>Model</type>
<code>M001</code>
<message>The operation has not been classified into a resource group</message>
<component>RedeemExceptionProcessRequestDTO</component>
<property>idvTotalAccountValueAt</property>
</documentationError>
</documentationErrors>
9

Take some time to digest all of the above and then propose a design that we can discuss.

Step 8 Build, test, repeat

You might also like