Wednesday, March 20, 2013

Automatic API Documentation


Documentation of API is always needed. Some protocols and standards support better documentation then others. Soap for instance supports better documentation than rest, but still needs explicit documentation so that clients can know how to use it.
Rest is known as a more problematic protocol since it is not self-documented.
Another issue is of course the problem that the code changes often after the spec has been written.
For this there a frameworks that create documentation from your code, and can be a part of your site.
This way the documentation is up to date and is available at all times.
There are multiple frameworks that do this. A list are:

In this blog I will describe the enunciate framework, since this framework give a rich output, and covers multiple protocols, including the option to generate client code in multiple languages to consume the rest api.
The current downside of enunciate is its documentation that is very sparse. So I will show you how to get a site up and running.
Many frameworks use proprietary annotations for the documentation which can be a hindrance if you want to change the framework. Enunciate used javadoc that is above your rest interface for documentation. It is a pity that they do not support the annotations that are part of JAX-RS (like @Description)
For example:
       /**
        * Gets the location.
        *
        * @param location free text location including all fields (street, city)
        * @return the location after it has been enriched
        * @throws ServiceInternalException the service internal exception
        */
       @GET
       @Path("/lookup/simple/{location}")
       LocationLookupResult getLocation(@Description("String of location, your may enter the full address in one string")@PathParam("location") String location);

The result will be:
Enunciate can be run from the command line, or be added to you maven project.
<plugin>
       <groupId>org.codehaus.enunciate</groupId>
       <artifactId>maven-enunciate-cxf-plugin</artifactId>
       <version>1.26.2</version>
       <executions>
              <execution>
                     <goals>
                           <goal>docs</goal>
                     </goals>
                     <configuration>
                           <docsDir>${project.build.directory}/docs</docsDir>
                           <configFile>./src/main/resources/enunciate.xml</configFile>
                     </configuration>
              </execution>
       </executions>
       <dependencies>
       </dependencies>
</plugin>

The secret to configuring enunciate is the enunciate.xml file, you need to configure this file properly for it to work, and all configuration is done in this file, for example:
<enunciate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="
           http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd"
       label="Alis Documentation">
       <api-import pattern="com.mycompany.interfaces.*" />
       <api-import pattern="com.mycompany.interfaces.soap.*" />
      
       <namespaces>

       <services>
              <soap defaultSoapSubcontext="/services/" />
              <rest defaultRestSubcontext="/api/">
              </rest>
       </services>
       <webapp disabled="true"></webapp>

       <!-- <api-classes> -->
       <!-- <include/> -->
       <!-- <exclude/> -->
       <!-- </api-classes> -->
       <modules>
              <disable-rule id="csharp.warnings" />
              <disable-rule id="c.warnings" />
              <disable-rule id="obj-c.warnings" />
              <docs docsDir="api" title="ALIS API" includeDefaultDownloads="true" includeExampleXml="false"
                     disableRestMountpoint="true" copyright="copyright" forceExampleJson="true">
              </docs>

              <basic-app disabled="true" />
              <c disabled="true" />
              <csharp disabled="true" />
              <jaxws-ri disabled="true" />
              <jersey disabled="true" />
              <obj-c disabled="true" />
              <amf disabled="true" />
              <gwt disabled="true" />
              <jboss disabled="true" />
              <object-c disabled="true" />
              <rubby disabled="true" />
              <java-client disabled="true" />
              <jaxws-client disabled="true" />


              <xml forceExampleJson="true" />
              <jaxws-support disabled="false" />
              <cxf disabled="false" enableJaxrs="true" enableJaxws="true" />
              <jaxws disabled="false" />
              <spring-app disabled="false" mergeWebXML="./src/main/webapp/WEB-INF/web.xml">
                     <war mergeWebXML="war/WEB-INF/web.xml"/>
                     <springImport uri="classpath:/servicesApplicationContext.xml" />
              </spring-app>
       </modules>
</enunciate>

You can have enunciate create a site or you can merge enunciate into your own site. Enunciate supports of course jax-rs with cxf jersy or spring.
The result of the enunciate process is a folder in your target folder.
If you want to add this manually to your site you need to configure the maven-war-plugin to include the following folders: docs/, docs/css, docs/js (assuming your folder is docs, defined in the maven-enunciate-cxf-plugin).

No comments:

Post a Comment