Introduction to the

With the popularity of mobile clients, back-end systems need to open up more and more apis for clients to use. Writing and managing API documentation is a challenge, and it must be kept up to date as the API changes, but writing documentation is also a burden.

A better practice is to put documentation in code that developers can modify as they write the code. The tool then extracts the document from the code and produces a user-friendly format. Such tools already exist, such as Javadoc in Java. Here we introduce apiDoc, a very lightweight, Restful API automatic document generation tool for almost any popular language.

website

The installation

ApiDoc is based on NodeJS implementation, so you need NodeJS and NPM environment first. And then through:

$ npm install apidoc -g
Copy the code

Install apiDoc globally. After that, you can execute the following command to generate the document:

$ apidoc -i src -o dest
Copy the code

The command reads all code files from the “SRC” subdirectory of the current working directory, extracts the documentation comments for apiDoc, and generates an HTML document stored in the “dest” subdirectory. After executing, the user can open “index.html” under “Dest” to read the document.

The “apidoc” command supports many parameters. The common ones are:

  • -t template

    • The document is generated based on the template in the template subdirectory. By default, the default apiDoc template is used.
  • -f “.*\.py$”

    • Only Python code is parsed. Parameters following -f are matched based on the re. You can set multiple -f parameters.
  • -h

    • The help information about the command is displayed.

The configuration file

To run apidoc, you need to have a configuration file named “apidoc.json” in the root directory (SRC in the example above). Here is an example of a standard profile:

{
  "name": "Movie Site Interface Document"."version": "0.1.0 from"."description": "Internal documents, please do not share."."title": "h5.com"."url" : "https://movie.52kfw.cn/index.php/api/movie"."sampleUrl": "https://test.52kfw.cn/index.php/api/movie"."header": {
    "title": "Introduction"."filename": "header.md"
  },
  "footer": {
    "title": "The bottom"."filename": "footer.md"
  },

  "template": {
    "withCompare": true."withGenerator": false}}Copy the code
  • Name, Version, and Description – The contents of these three configuration items are displayed at the top of the generated document, where name is the title of the entire document.

  • title

    • The title of the web page, displayed on the browser TAB.
  • url

    • The prefix for each API address in the document.
  • sampleUrl

    • When this item is present, there is a Sample Request test section at the end of each API document. This configuration item is the prefix of the test API address.
  • header, footer

    • The header and tail of the page. This configuration item is useful when multiple pages have the same beginning and end. Subconfiguration items
  • title

    • The title displayed in the menu bar on the left side of the page.
  • filename

    • A template file pointing to the header or footer of a page. ApiDoc uses Markdown files.
  • template

    • withCompare
      • The generated documents have version comparison capabilities. That will be explained later. The default value is true.
    • withGenerator
      • The resulting document has a paragraph at the end of the page that indicates that the document was generated by apiDoc, and that this represents respect for the author. The default value is true. Let’s simply write down the header and tail Markdown files and put them together with “apidoc.json”, in the “SRC” directory.
  • header.md

Introduction of # #> This document is for internal use only. - email: [email protected] - wx: superveCopy the code
  • footer.md
Copyright © 2017-2019 [H5.com](http://www.h5.com/) All Rights ReservedCopy the code

API documentation comments

Apidoc generates documentation from the data in our code in a specific format.

JavaScript example:

/** ** @api {post} /register User registration interface * @apiname register * @apigroup User management * @apiVersion 0.1.0 * @apidescription User registration is complete * * @apipermission admin * * @apiparam {string} username username * @apiparam {string} password password * @apiparam {string} Email address * @apiparam {string} phoneNumber mobile phoneNumber * * @apisuccess (success-200) {string} code response status code * @apisuccess (SUCCESS-200) {String} MSG Response description * @apisuccess (success-200) {Object} data Returns data, * @apisuccess (success-200) {int} data.count Total number of records * @apisuccess (success-200) {Object[]} data.list List of records * * * @apisuccessexample {json} Succeeded in registering - example: * Succeeded in registering * HTTP/1.1 200 OK * {* code:0, * MSG:'success'. * Data :{} *} * * @APIError (failure-500) {String} code Response status code * @APIError (failure-500) {String} MSG Prompt message * * HTTP/1.1 404 Not Found * {* code:1, * MSG:'not found'}, * * /function register() {} /** ** @api {get} /list User list interface * @apiname useList * @apigroup user management * @apiVersion 0.1.2 * @apidescription User list latest interface * * @APIParam {int} Page page number * @APIParam {int} size Number of pages per page * @APIParam {string} orderBy sorting field * * @apisuccess (SUCCESS-200) {String} code Response status code * @apisuccess (success-200) {String} MSG Response description * @apisuccess (success-200) {Object} Data Returns data, * @apisuccess (success-200) {int} data.count Total number of records * @apisuccess (success-200) {Object[]} data.list List of records * * @apisuccessexample Success-Response: this is an example of a return result * HTTP/1.1 200 OK * {* code:0, * MSG:'success',
 * data:{}
 *  }
 *
 * @apiUse UserNotFoundError
 */

function useList() {}Copy the code

As you can see, a document comment consists mainly of a series of arguments beginning with the @ symbol:

  • @api {get} /users/:user_id Request User Information

    • {get} defines the HTTP request as GET
    • The API address is /users/:user_id
    • The name of the API in the document is Request User Information
  • @ apiVersion 0.1.0 from

    • The version number of the API, shown by default to the right of the API name. This parameter can be used to compare different versions, as described later
  • @apiName GetUser

    • The API name does not affect the document
  • @apiGroup User

    • The API group name, document content and the API group in the menu bar are displayed together for easy reading
  • @apiPermission admin

    • The API access permission is displayed under the API address by default in the document. This item can be omitted if permission is not required.
  • @apiDescription API to get the user information.

    • A detailed description of the API is displayed by default under the API name
  • @apiExample Example usage:

    • The next line of this parameter is the content of the example until the empty line ends. More than one @apiExample can be defined. By default, it is listed in the document as a tag named “Example Usage:”.
  • @apiParam {Number} user_id The user’s unique ID.

    • API parameter field description, “{Number}” defines the field type, “user_id” is the field name, followed by the field description. Multiple @APIParam fields can be defined.
  • @apiSuccess {String} name Name of the User.

    • The API returns fields after success, as @APIParam, “{String}” defines the field type, “name” is the name of the returned field, followed by the field description. Multiple @apisuccess fields can be defined.
  • @apiSuccessExample {json} Success-Response:

    • Show an example of a Response Response after a successful API return. “{json}” indicates that the Response body is json. The downlink of this parameter is the response body until the end of the empty line. You can define multiple @apisuccessexample, which by default is listed in the document as a tag named “success-Response:”.
  • @apiError UserNotFound User was not found.

    • API error return, “UserNotFound” is the error name, followed by the error description. Multiple error returns can be defined.
  • @apiErrorExample {json} Error-Response:

    • Show an example of a Response Response to an API error, “{json}” indicating that the Response body is of JSON type. The downlink of this parameter is the response body until the end of the empty line. You can define multiple @APIerRorexample, which by default will be listed in the document as a tag named “error-Response:”.
  • @apiSampleRequest http://localhost:5000/users/:user_id

    • This document provides the API Sample test address. This parameter can be omitted if the “sampleUrl” parameter is configured in “apidoc.json”, unless the API test URL is specified.

Reuse of parameter information

Many times, different apis have the same documentation content, such as the same sample success response, or the same error return. When there are a lot of apis, one change requires multiple changes to the API document, which can be cumbersome. Is it possible to define a macro and refer to it in API documentation comments, just like writing C code? The answer is yes, in apiDoc, it is called inherit. First, you define the macro with @apideFine in the source code comments.

For example, the following comment defines the example UserNotFound error and its response in a macro named UserNotFoundError. Thereafter, import the macro via @apiUse UserNotFoundError wherever you need to use the document

/** * @apidefine UserNotFoundError ** @apiError Error ** @apierRorexample {json} * HTTP/1.1 404 Not Found * {* code:1, * MSG:'list not found'. *} */ /** ** @api {post} / CXPT Category list * @apiname categoryList * @apigroup Category * @apiVersion 0.1.0 * @apidescription Category List Display * * @APIParam {string} Page Page number * @APIParam {string} size Number of pages to be obtained * * @apisuccess {string} code Mandatory parameter description. * @apisuccess {String} data * @apisuccess {Object} data * @apisuccess {Object[]} data.list * @apisuccess {Object[]} data.list HTTP/1.1 200 OK * {* code:0, * MSG:'success',
 * data:{}
 *  }
 *
 *  
 * 	@apiUse UserNotFoundError
 *  
 */
function categoryList() {}Copy the code

How do you manage macros when they are more defined? We can move the macro definition out of the code. Let’s create a file “_apidoc.js” in the “SRC” root directory. Then move the above definition of UserNotFoundError into this file.

src/_apidoc.js

/** * @apidefine UserNotFoundError ** @apiError Error ** @apierRorexample {json} * HTTP/1.1 404 Not Found * {* code:1, * MSG:'Classification information does not exist'}, * * /Copy the code

Execute the apidoc command to see the effect. Is it the same as in the previous example? In a practical project, it is recommended that all macro definitions be in “_apidoc.py” whenever possible. And some people say, well, what if this file is too big? You can split up multiple files, just remember to give them a meaningful name.

The @APIVersion version information is added to the macro definition, indicating that the macro is only valid for a specific version. src/_apidoc.js

/** * @apidefine UserNotFoundError ** @apiVersion 0.1.0 ** @apiError Error ** @apierRorexample {json} Examples of errors: * HTTP/1.1 404 Not Found * {* code:1, * MSG:'Classification information does not exist'}, * * /Copy the code

Defining access rights

Above we saw that the @apiPermission parameter defines access to the current API. What if the reader of the document wants to know more about this permission? We can define the details of each permission with @apidefine. src/_pri.js

/** * @apidefine admin Admin permission ** Note that this interface must use the administrator permission to use ** @apiVersion 0.1.0 ** */Copy the code

With this definition, there will be an “I” sign after the “admin” permission name appears in the document. Click the mouse will pop up the details of “admin”.

Historical version comparison

When an API is updated, you don’t have to spend a lot of effort to find out exactly what’s changed, just compare it to the documentation. When multiple versions are defined in a document comment, the generated document page contains a drop-down list of version numbers.

Clicking on one of the historical versions will bring up comparison information, highlighting, strikeouts and so on to show you where changes have been made.

/** ** @api {get} / CXPT user list interface * @apiname useList * @apigroup Users * @apiVersion 0.1.0 * @apidescription * * @apiParam {int} myparam parameter description * * @apisuccess {String} code Return parameter description, * @apisuccess {String} data * @apisuccess {Object} data * @apisuccess {Object[]} data.list * @apisuccess {Object[]} data.list HTTP/1.1 200 OK * {* code:0, * MSG:'success', * data:{} *} * * @apiError error * @apierRorexample {json} error-response: HTTP/1.1 404 Not Found * {* code:1, * MSG:'user not found'. *} */ /** ** @api {get} / CXPT user list interface * @apiname useList * @apigroup Users * @apiVersion 0.1.1 * @apidescription * * @apiParam {int} page specifies the page number. 1 * * @apisuccess {String} code * @apisuccess {String} MSG @apisuccess {Object} data * @apisuccess {int} data.count * @apisuccess {Object[]} data.list * @apisuccessexample Success-Response: HTTP/1.1 200 OK * {* code:0, * MSG:'success', * data:{} *} * * @apiError error * @apierRorexample {json} error-response: HTTP/1.1 404 Not Found * {* code:1, * MSG:'user not found'}, * * /function fn() {}Copy the code

How to add this historical version information. The simple thing to do is to copy and back up the original API documentation comments to _apidoc.js every time the API documentation changes, and then modify it. Don’t forget to update the version number when you’re done.

And then run it, and you can do version comparisons. The @apidefine macro definition can also have a historical version. Note that this version number matches the version number of the API comments.

For example, if we add @apiuse UserNotFoundError to the comment for the “0.0.1” version of the above GET method, executing the apidoc command will fail.

Because it can’t find the @apideFine UserNotFoundError definition for the “0.0.1” version (the version we specified in the previous example was @APIVersion 0.1.0). Therefore, the “0.0.1” version of the @apidefine UserNotFoundError command must be supplemented to run successfully.

extension

Enable APIDOC to enter Chinese

  1. Find your apidoc path after NPM installation and open api_group.js (node_modules\apidoc\node_modules\apidoc-core\lib\workers\api_group.js)
  2. //group = group.replace(/[^\w]/g, ‘_’)
  3. The source file you use to generate the document must be UTF-8, otherwise the generated code will be garbled