Documenting microservices

In this section, we are going to learn how to use Swagger to document APIs. Swagger is an API manager that follows the Open API standard, so that it is a common language for all the API creators. We will discuss how to write definitions and why it is so important to agree on how to describe resources.

Documenting APIs with Swagger

Documentation is always a problem. No matter how hard you try, it will always eventually go out of date. Luckily, in the past few years, there has been a push into producing a high quality documentation for REST APIs.

API managers have played a key role in it, and Swagger is particularly an interesting platform to look at. More than a module for documentation, Swagger manages your API in a such way that gives you a holistic view of your work.

Let's start installing it:

npm install -g swagger

This will install Swagger system-wide, so it will be another command in our system. Now, we need to create a project using it:

swagger project create my-project

This command will allow you to choose different web frameworks. We are going to choose Express, as it is the one that we have already been using. The output of the preceding command is shown in the following screenshot:

Documenting APIs with Swagger

This screenshot is showing how to start a project with Swagger

Now we can find a new folder, called my-project, that looks like the following image:

Documenting APIs with Swagger

The structure is self-explanatory and it is the common layout of a Node.js application:

  • api: Here, our API code will lay down
  • config: All the configuration sits in here
  • node_modules: This is a folder with all the dependencies required to run our application
  • test: This is where Swagger has generated some dummy tests and where we could add our own tests

Swagger comes with an impressive feature: an embedded editor that allows you to model the endpoints of your API. In order to run it, from within the generated folder, execute the following command:

Swagger project edit

It will open Swagger Editor in the default browser, with a window similar to the following image:

Documenting APIs with Swagger

Swagger makes use of Yet Another Markup Language (YAML). It is a language that is very similar to JSON, but with a different syntax.

In this document, we can customize a number of things, such as paths (routes in our application). Let's take a look at the path generated by Swagger:

/hello:
  # binds a127 app logic to a route
  x-swagger-router-controller: hello_world
  get:
    description: Returns 'Hello' to the caller
    # used as the method name of the controller
    operationId: hello
    parameters:
      - name: name
        in: query
        description: The name of the person to whom to say hello
        required: false
        type: string
    responses:
      "200":
        description: Success
        schema:
          # a pointer to a definition
          $ref: "#/definitions/HelloWorldResponse"
      # responses may fall through to errors
      default:
        description: Error
        schema:
          $ref: "#/definitions/ErrorResponse"

The definition is self-documented. Basically, we will configure the parameters used by our endpoint, but in a declarative way. This endpoint is mapping the incoming actions into the hello_world controller, and specifically into the hello method, which is defined by the id operation. Let's see what Swagger has generated for us in this controller:

'use strict';

var util = require('util');

module.exports = {
  hello: hello
};

function hello(req, res) {
  var name = req.swagger.params.name.value || 'stranger';
  var hello = util.format('Hello, %s!', name);
  res.json(hello);
}

This code can be found in the api/controllers folder of the project. As you can see, it is a pretty standard Express controller packed as a module (well-cohesioned). The only strange line is the first one in the hello function, where we pick up the parameters from Swagger. We will come back to this later, once we run the project.

The second part of the endpoint is the responses. As we can see, we are referencing two definitions: HelloWorldResponse for http code 200 and ErrorResponse for the rest of the codes. These objects are defined in the following code:

definitions:
  HelloWorldResponse:
    required:
      - message
    properties:
      message:
        type: string
  ErrorResponse:
    required:
      - message
    properties:
      message:
        type: string

This is something really interesting, although we are using a dynamic language, the contract is being defined by Swagger so that we have a language-agnostic definition that can be consumed by a number of different technologies, respecting the principle of technology heterogeneity that we were talking about earlier in Chapter 1, Microservices Architecture, and Chapter 2, Microservices in Node.js – Seneca and PM2 Alternatives.

After explaining how the definition works, it is time to start the server:

swagger project start

This should produce an output that is very similar to the following code:

Starting: C:my-projectapp.js...
  project started here: http://localhost:10010/
  project will restart on changes.
  to restart at any time, enter `rs`
try this:
curl http://127.0.0.1:10010/hello?name=Scott

Now, if we follow the instructions of the output and execute the curl command, we get the following output:

curl http://127.0.0.1:10010/hello?name=David
"Hello David!"

Swagger is binding the name query parameter to the Swagger parameter specified in the YAML definition. This may sound bad, as we are coupling our software to Swagger, but it gives you an immense benefit: Swagger allows you to test the endpoint through the editor. Let's see how it works.

On the right-hand side of the editor, you can see a button with the Try this operation label, as shown in the following screenshot:

Documenting APIs with Swagger

Once you click it, it will present you a form that allows you to test the endpoint, as shown in the following screenshot:

Documenting APIs with Swagger

There is a warning message on this form about cross-origin requests. We don't need to worry about it when developing in our local machine; however, we could have problems when testing other hosts using the Swagger Editor.

Note

For more information, visit the following URL:

https://en.wikipedia.org/wiki/Cross-origin_resource_sharing

Enter a value for the name parameter, and after that, click on Send Request, as shown in the following image:

Documenting APIs with Swagger

This is a response example using Swagger Editor to test the endpoint

Be aware that, for this test to work, our app server has to be up and running.

Generating a project from the Swagger definition

Until now, we have been playing with Swagger and the generated project, but we are now going to generate the project from the swagger.yaml file. We will use the already generated project as a starting point, but we will add a new endpoint:

swagger: "2.0"
info:
  version: "0.0.1"
  title: Stop Words Filtering App
host: localhost:8000
basePath: /
schemes:
  - http
  - https
consumes:
  - application/json
produces:
  - application/json
paths:
  /stop-words:
    x-swagger-router-controller: stop_words
    get:
      description: Removes the stop words from an arbitrary input text.
      operationId: stopwords
      parameters:
        - name: text
          in: query
          description: The text to be sanitized
          required: false
          type: string
      responses:
        "200":
          description: Success
          schema:
            $ref: "#/definitions/StopWordsResponse"
  /swagger:
    x-swagger-pipe: swagger_raw
definitions:
  StopWordsResponse:
    required:
      - message
    properties:
      message:
        type: string

This endpoint might sound very familiar to you, as we unit tested it earlier in this chapter. As you probably know by now, the Swagger Editor is quite cool: it provides feedback as you type on, about what is going on in the YAML file, as well as saves the changes.

The next step is to download the Swagger code generator from https://github.com/swagger-api/swagger-codegen. It is a Java project, so we are going to need the Java SDK and Maven to build it, as follows:

mvn package

Codegen is a tool that allow us to read the API definition from the Swagger YAML and build the basic structure for a project in a language of our choice, in this case, Node.js.

The preceding command in the root of the project should build all the submodules. Now, it is as easy as executing the following command in the root of the swagger-codegen folder:

java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i my-project.yaml -l nodejs -o my-project

The Swagger code generator supports a number of languages. Here, the trick is that when using it for microservices, we can define the interface and then use the most appropriate technology to build our service.

If you go to the my-project folder, you should find the full structure of the project in there, ready to start coding.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.170.187