It is inevitable that any software application being developed will at some point need to be integrated or have the ability to easily integrated with other software projects. The best way to do that is through APIs, the downside is for a long time there hasn’t been any industry standard for designing and documenting APIs.
In this post, I will discuss a few scenarios and reasons why developers will often need to develop API’s and then how we can develop a Simple Web API using node.js and then document that API using Swagger.
Software development is a complex process requiring more than just writing code
We need to plan and define the base of our application first. This is what is commonly referred to as Solution Architecture. Involving more than just thinking about what you need your application to do, but rather how you intend to structure the application to meet the needs of your users.
Software solutions are broken up into areas and objects of interest, which we call
Similarly to property development, software development needs to start from a solid foundation. Although software development approach may be slightly different in that you can start developing different areas of the application independently and ultimately wire up the different components of the application at a later date.
Producing feature after feature without actually caring about code quality may work initially, but after a period of time it will start becoming un-maintainable and ultimately slower to continue adding new features and eventually your software development costs just start to become a bottomless pit for money! Typically referred to as brute-force-driven development.
The issue is that software development is nothing more than just building blocks of functionality on top of one another. If the lower layers of our program are poorly designed, then the whole solution will suffer because of this.
Customer Driven Development
A customer may contact you, with a requirement for a new service their company would like to launch and requires a solution based on some very sketchy details and totally unrealistic timescales. Customers also generally expect comprehensive documentation explaining how to make use of the feature.
Budget constraints are always an issue and customers never have the appropriate infrastructure in place to live up to their expectations!
This often works hand in hand, with the perception that Software is a malleable entity, in that you can easily bend and shape it to your needs as required. For the most part that is accurate, however, it is the definition of easy that becomes the sticking point.
Everything is easy once you know how
A vast majority of applications will require some mechanism to store and retrieve data from some sort of Data Repository. This may require some actions to perform on the data, either to transform it to a state it is required or even to break it up into smaller pieces that can be sent/extracted to several different repositories.
Typically this is implemented via a series of
services. Modern application stacks these are implemented as RestFul Services. If you’re new to developing API’s you may want to quickly read through What is a Rest API .
We’ll go through the process of developing a Web API making use of node.js and Swagger.
In order to build a RESTful API we need to understand how to ; <
- How to specify a web API
- How to implement routes
- How to test your API
- Content negotiation
- What is CORS
- API Versioning
- What is HATEOS ?
Simple node Web Server
Creating a web-server in node is trivial task, and ultimately only involves an initial 8 lines of code
This web server doesn’t do much, but it works. Assuming you have saved the code above to a file
server.js you can simply run it from the terminal window by navigating to the directory and
node server.js .
This is a really simple web server, and it serves as the basis of a typical Web API. However, to make it truly functional and robust requires additional development effort. <
Get your swagger on
We could go through the whole process of painfully developing each layer of our application, but who’s got time for that? The customer wants the API today! So we’ll go ahead and use the swagger API generator.
When developing API’s the key requirement to enable other developers to use your API is to create documentation. We don’t want to spend hours writing documentation when we can just generate it and wouldn’t it be cool if we could generate a lot of the Grunt work too?
Enter Swagger , a popular open-source framework to help you develop and document RESTful APIs.
You may need to install swagger if you haven’t done so already. It’s simple just execute the following from the terminal
We can now generate our project
Ensure you select
Express when prompted for which framework to use. Once completed, the project directory will looks as follows:
- Api – everything related to the API development, the controllers, mocks, helpers.
- config – configuration
- test – test for controllers and helpers
Before we run and inspect the new application, we first need learn about a new tool that has also been installed as part of the Swagger. The
Swagger Editor is an elegant browser-based editor which really simplifies developing a web API.
The swagger editor helps with testing your API, by providing you a UI to access your API functionality. It also provides
- Validation and endpoint routing
- Docs on the fly generation
- Easy-to-read Yaml.
We can launch our application and the Swagger UI
Then open a new terminal window navigate to your project directory
If everything went well the editor should open your browser. On the right side of the page you should notice the example path for a GET request to /hello, so open the tab and, at the bottom, click on the button try this operation.
Take some time to explore the
x-swagger-router-controller: This is the controller, the file we have in the
The HTTP methods are listed.
operationId: This refers to the function, in the controller, in charge of the business logic.
parameters: The list of required parameters are defined here. The parameter name is the only one and you may see that it is in the path, it is not required and it is a string.
Swagger shows its potential:
You can define a different response for each situation, given the HTTP status or errors, a particular response can be defined.
In the example, for the status,
200there is a pointer $ref to a response definition while for other statuses, we go to default with its own
In order to keep the yaml file clean, we can define all our response under definitions while at the same time reusing the definition for different responses.
I have removed the comments for brevity so we can focus solely on the generated code. I recommend go through the comments as they actually do provide some additional information. Unlike most comments, I have encountered in code bases!
At first glance, there is nothing too complicated here. However, I just wanted to point out the
req object (Request) has a new property available, which is not typical of the native request object, it has a
swagger property. The swagger property will enable access to any prperties that have been defined i.e. Parameters.
Working with Mocks
During the course of your development, you may not necessarily want to access the database or whatever data repository. Ideally, you want things to be quick and have the ability to create certain data conditions you want to develop against. This is where working with Mock objects comes into its own.
Swagger makes working with Mocks really easy. You don’t even have to create your Mock objects using the code, its simply just a matter of editing your
yaml file in the swagger editor.
In order to edit the Mocks. We need to start the application again. However, this time we are going to instruct it to make use of the
adding the flag -m to the command start Swagger in mock mode. We now need to open the second terminal window and start the editor again.
Create New Mock
We now want to create our new Mock for our sample application. In our example, we want to return a list of coffee cafe’s that exist in a geographical area. To start off with we will keep it really simple and just return a full list of cafe’s.
To Do this, in your Swagger Editor just
Delete contents. Now we will add our own Methods
Lines 1 – 19 just supply additional pre-amble information about your API declaration. Explicitly detailing how the API is developed using Swagger and the expected return types etc.
You could omit this information, as it may not be strictly necessary, but it is best practice to add it.
Lines 20 – 35 , actually start defining our API. We are defining a cafe
controller with one
Get method . At this stage we are not defining any additional parameters. We also define a
Response which is going to comprise of a
GetCafeListResponse, also if there is a failure we will aim to provide an error response.
Now lets go ahead and define our
In the example, we defined an
operationId, which contains the Method on the controller action which will be used to service the request. If we attempt to send a request we’ll just get a sample response.
Create a method to enable adding a new cafe to the list.
You do not need to use the Swagger Editor to edit your
You can use any text-based editor just navigate to
You would continue to do so for all the methods you want to define. All code is available on Github
Start the Coding
We’ll go ahead now and implement the logic for our system. The back-end for this system is going to be MongoDB. So we’ll need to take care of some pre-requisites.
One of the pre-requisites is to ensure MongoDB is installed. You can make use of either the Docker Images or ll-mongodb-ubuntu-14-04/” target=”_blank” rel=”noopener noreferrer”> install MongoDb on your ubuntu desktop .
We also need to install
lodash into our project
We also need to update our
The only thing really worth explaining in the code above, is that Mongoose no longer has a default promises library so we will configure Mongoose to use bluebird.
If not installed simply :
npm install bluebird
We also need to add some Models so we need to create a new folder called
models and add a new file
Implement Controller Methods
We’re now able to complete the controller logic in the
Swagger helps to develop a robust RESTful API while at the same time providing an elegant documentation that can boost up cooperation among developers.
Taken the approach of Documenting as you go, helps you to focus on what you’re developing.
- How to use Github actions to build & deploy Github nuget packages - October 14, 2021
- How to implement cross cutting concerns with MediatR Pipeline Behaviours - October 5, 2021
- Understanding the difference between Queue and Stack Data Structure - September 22, 2021