How to create your own little Restful Web API without getting lost in the process — Part 1

Gabry Martinez
9 min readFeb 6, 2018

--

In my previous posts I wrote about Web API’s, microservices and serverless architecture models. All these were just pure words, and words with the time get boring.

In this post I’ll put some of these concepts into practice. So, if you are like me and you are getting started into this cloud/microservices/serverless world, give your self some time to put some code on this subject. We’ll go over the HTTP protocol and the best practices on Restful API’s design. Then use all these concepts to build a basic WEB API with ASP.NET Core. And later, deploy it to a cloud service like Azure, in a second post.

The required software that you need to do this demo application is:

  • Visual Studio Community version 2017.
  • Latest DotNetCore SDK
  • A REST client for testing purposes. You can use RESTLet Studio or any other you like.
  • SQL Server Express 2017 or 2014 version.

What the application will do?

A WEB API: one database with three tables: Book, Category and User. With these you’ll create a small book catalog, along with some quick filters to query the books catalog.

The HTTP protocol

It is mandatory to talk a bit about the HTTP protocol that a Web API uses at its backend: It is a client-server protocol: A server, the piece that handles all the requests and a web browser or recipient which initiate them. The messages sent and received are called requests and responses. Between these requests and responses there are several entities performing different operations and acting as gateways.

An example of an HTTP message request is something like the following:

GET/HTTP/1.1
Host: localhost:8000
Accept-Language: fr

First line in this message corresponds to the HTTP method: usually a verb like GET, POST or a noun like OPTIONS or HEAD, which defines the operation that the client wants to perform. Typically, a client wants to fetch a resource (GET verb) or post the value of an HTML form (POST verb), though more operations may be needed in other cases. After the verb, comes the path of the resource to be fetched and finally the version of the protocol. For some methods like POST there is also a body, which contains the resource sent. Optionally also there are headers that provide additional information for the server.

A response from a server has the following elements:

HTTP/1.1 200 OK
Date: Sat, 09 Oct 2017 14:28:02 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2017 20:18:22 GMT
ETag: “51142bc1–7449–749b075b2891b”
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html

First line corresponds to the version of the protocol, a status code (200), a status message (OK), headers like the ones from the request, and optionally a body that contains the fetched resource.

I won’t get into the details of the rest of the verbs, since there are plenty of posts that you can find about them. I’ll put some references at the bottom of this posts that I found very clear and well documented.

URL’s design

An URI is an identifier for a resource in the HTTP context. Within an API, a URL is the interface to interact with the resources that it serves. Thus it needs to be self explained, standard, and intuitive. URL’s are identifiers, so an URL is compound by nouns, not verbs. For our example application we have book, category, and user. Note also the usage of plural in the URI. The URI’s depending on the message sent could be something like these:

GET /books — Retrieves a list of books
GET /books/12 — Retrieves a specific book
POST /books — Creates a new book
PUT /books/12 — Updates book #12
PATCH /books/12 — Partially updates book #12
DELETE /books/12 — Deletes book #12

Examples with relationships

GET /categories/12/books — Retrieves list of books for category #12
POST /categories/12/books — Creates a new book in category #12

Handling the response from the server

In the HTTP protocol exists a list of response status codes. Status codes are issued by a server in response to a browser’s request made. With over 70 HTTP status codes, make sure you use only the ones that are really relevant to the use case of your API. Most API developers on big companies use a very small subset of all HTTP codes. Once you decide which status code to use, you will also need to define which errors will also be mapped to its specific error code.

Here is a list of the most common ones:

204 NO CONTENT
304 NOT MODIFIED
400 INVALID REQUEST
401 UNAUTHORIZED
403 FORBIDDEN
404 NOT FOUND
500 INTERNAL SERVER ERROR

Security and Versioning

In terms of security, the rule is always use SSL. No exceptions. Today web API’s can be accessed from anywhere. Using SSL ensures communication and simplifies authentication efforts.
Regarding the versioning of the API’s, I have found some different opinions. But now seems that putting the version on the URL is becoming the standard as it really helps on managing compatibility between the API’s versions. An API is never going to be completely done, change is always a constant. What is important is how you manage change. Another recommendation is always document and announce to your users about deprecating methods and give some versions to your users before completely removing them.

The Web API application

Let’s start by defining the URL’s that we’ll use for our web API.

Methods for the Books controller:

GET /api/books : Gets all books in the database. Request body: None. Response body: Array of book items.
GET /api/books/{id} : Gets a book by its ID. Request body: None. Response body: A book item.
POST /api/book : Adds a new book. Request body: a new book item. Response body: A book item.
PUT /api/book/{id} : Update an existing book. Request body: a book item. Response body: None.
DELETE /api/book/{id} : Delete an existing book. Request body: None. Response body: None.

Categories controller

GET /api/categories/{categoryid}/books : Gets all books in the database that belong to the category with the provided Id. Request body: None. Response body: Array of book items.

Creating the project

If you like to use the console line, type the following on the developer command prompt inside a convenient path in your machine:

>dotnet new webapi

You will see a message that a template for the ASP.NET Core Web API has been created successfully and then the dotnet restore command is also executed.
Open the project on Visual Studio to start exploring the files that are part of it.

Otherwise if you want to create the project with Visual Studio IDE, select the New Project dialog and then select the Web API option.

A project has been created and it contains the basics for a Web API, with the required dependencies already on it too.

Exploring the generated project

Select the program.cs. file, there are two methods added: main and BuildWebHost. What this code is actually doing is that it creates a new webhost builder and then runs the webhost to start listening to the requests. It also instantiates a class called startup. The startup class is where it is set how each request is served.

Take a look to the startup.cs file. There are two main methods — configureServices and Configure. ConfigureServices is going to setup the dependency injection in ASP.NET Core, and the Configure method will be used to specify how ASP.NET Core will respond to individual HTTP requests.

The first thing to set up will be configuration options. There are some ways to manage the configuration data you can take a look of the complete list of options here, in this example we’ll use the json file format to keep our configuration data.

Go to the Startup.cs file and add the following lines to your Startup class constructor method. After the changes it should look like this:

You may noticed already that we have some new lines for the AddDbContext method. We’ll explain this in a bit.

Create the data model

A model is an object that represents the data in the app. In this case, we have three data objects: book, category and user. We’ll add a class for each one of them. Add an entities folder and next, add a new class Book and then Category class.

For managing the users data, we’ll use the Microsoft.ASP.NET.Core.Identity. By default it is not added. In order to do so, go to the Tools Menu -> Nuget Package Manager, and select the Package Manager Console option.
A small window should be open with this title. On this type:

PM> Install-Package Microsoft.AspNetCore.Identity

Our User class will extent the asp.newUsers class with a first name and last name columns. Let’s add this new User class and add the following code:

Notice that there is a using Microsoft.AspNetCore.Identity, so we can use the IdentityUser class, which inherits to our User class.

Now that we have our models defined, we can add a Database Context, which will hold the data between the database and the application. Add a new folder named Data, and add a new class on it with the name BooksCatalogDbContext.cs This context will be derived from IdentityDbContext, for our Identity provider.

As any version of ASP.NET core, there are more than one way to do the configuration of the Database that will be used for our Web API. Personally I prefer to hold the data of the connection string inside a configuration file. This is a very convenient way since it can be changed in any moment without having to change the Application code.

First add the information in the configuration file: appsettings.json. You should add a new section called ConnectionStrings. Inside of this section should be the DefaultConnection which is the one to be used.

The default connection does not include any credentials data. We are using Windows Authentication for this case. But you should change it once this is deployed to our Azure server.

Take a look back at the startup.cs file. At the ConfigureServices method. Here is the place where you should select the connection string for the database context, the provider to be used for the Database Context of the Web API.

services.AddDbContext<BooksCatalogDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString(“DefaultConnection”)));

In order to use the Sql Server provider, it is needed also to add the EntityFrameworkCore package. There are several options here, for the database, and you should feel free to use any you like. If you do not have a SQL server installed, you can use local db or In memory database, these last two do not require any database engine.

For this example, we are using the Code first strategy, which means we do not have any existing database, and we’ll create it based on the classes that we have already defined in our Database Context. If you would have a scenario where there is an existing database, you would need to use the Database first strategy. This subject will not be covered in this example.

Now that the classes of the entities are already defined, we can create our database.

Install the Entity Framework Core tools, which includes the code migrations. At the Package Manager type:

>Install-Package Microsoft.EntityFrameworkCore.Tools

This will add the tools for the code migrations generation. Then run the following command:

> Add-Migration InitialCreate

This will generate the code scripts that will create a new database with the Identity Provider tables too. You can take a look of the generated code at the Migrations folder. You should have the Initial Create file and the first snapshot of the database model.

Now run the update database command, so the code is executed.

PM> Update-Database

At this moment the database is created. On the next post we’ll covered the part for the code of the GET, POST, PUT and DELETE actions, and we’ll deploy the application to our Azure Server.

Summary

In this part of the exercise, ASP.NET core and Entity Framework Core were used to create a simple Web restful API. We covered the configuration of the db provider, the creation of the entities classes along with the Database context and finally the creation of the database, in this case for Code First strategy. We’ll finish the API at the second part along with the deployment at our Azure Server. You can download the source code of the example here

Resources

See you at the part 2.

Happy Coding!

--

--

Gabry Martinez
Gabry Martinez

Written by Gabry Martinez

Software engineer, coding software for web and cloud. Love software architecture, c#, unit tests and open source. TRX, books&coffee in my free time.

Responses (1)