testing

#CASBAN6: Add a Swagger (OpenAPI) page to Azure Functions

#CASBAN6: Add a Swagger (OpenAPI) page to Azure Functions

Why?

Adding a Swagger page to any API project (not only with Azure Functions) is nowadays one of the most common steps. Implementing the OpenAPI specification makes your API easily testable during development, and in the end, it provides an interactive documentation page to your API consumers.

While these are the major advantages, you can go deeper into that topic on the OpenAPI website. Swagger has become the most popular implementation of the OpenAPI specification and is also available for Azure Functions.

Adding the NuGet

Adding the Swagger UI to our Azure Function needs another NuGet package:

Microsoft.Azure.WebJobs.Extensions.OpenApi

The documentation is only available on GitHub (at the time of writing this post, at least).

Getting started

Now that we have downloaded the NuGet package into our project, we need to configure three or four things in the Program.cs file of our Function app. In the ConfigureServices lambda of the Main method, add these lines:

services.AddSingleton<IOpenApiConfigurationOptions>(_ =>
{
    OpenApiConfigurationOptions options = new OpenApiConfigurationOptions
    {
        Info = new OpenApiInfo
        {
            Version = "1.23131.0",
            Title = "Serverless Blog API",
            Description = "This is the API on which the serverless blog engine is running.",
            TermsOfService = new Uri("https://yourdomain.com/tos"),
            Contact = new OpenApiContact
            {
                Name = "Your Name goes here",
                Email = "info@yourdomain.com",
                Url = new Uri("https:/yourdomain.com")
            },
            License = new OpenApiLicense
            {
                Name = "License",
                Url = new Uri("https://yourdomain.com/license")
            }
        },
        Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
        OpenApiVersion = OpenApiVersionType.V3,
        IncludeRequestingHostName = true,
        ForceHttps = false,
        ForceHttp = false
    };
    return options;
});

Let’s walk through that code. We are adding a new OpenApiInfo object filling all the details about contact, licence, etc. Then we configure additional items like the servers and the OpenAPI specifications version. Last, but not least, we are not forcing the Swagger page to use either http or https. This makes testing locally (especially on macOS) easier.

On Azure, the API gets redirected to https, anyway, so this should not be much of a problem. You can change this according to your needs.

If you are now debugging your Function app, you will see new endpoints in the console:

OpenAPI-endpoint-Azure-function-console

Opening the RenderSwaggerUI URL will lead you to your newly created Swagger page.

Attributing the Function methods

Now that we have our configuration in place, we finally can start to decorate our methods with the OpenAPI attributes. Let’s have a look at the GetList function for posts:

[OpenApiOperation("GET", "Post", Description = "Gets a list of posts from the database.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter("blogId", Type = typeof(Guid), Required = true, Description = "Id of the blog on which the posts exist", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter("skip", In = ParameterLocation.Query, Type = typeof(int), Required = true, Description = "skips the specified amount of entries from the results", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter("count", In = ParameterLocation.Query, Type = typeof(int), Required = true, Description = "how many results are being returned per request", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(HttpStatusCode.OK, "application/json", typeof(Post), Description = "Gets a list of posts")]
[OpenApiResponseWithoutBody(HttpStatusCode.Unauthorized, Description = "Response for unauthenticated requests.")]
[OpenApiResponseWithBody(HttpStatusCode.BadRequest, "text/plain", typeof(string), Description = "Request cannot not be processed, see response body why")]

Let’s go through the attributes. To add the endpoint to the Swagger page, add the OpenApiOperation attribute and specify the http method, a tag as well as the description. By setting the visibility to important, we make sure the field gets always shown. The tag is used to group endpoints on the Swagger page.

Depending on your endpoint, you may have parameters. You can add them by using the OpenApiParameter attribute. The In parameter specifies the usage location (path, query, header or cookie). In this project, I used only the default value (path) and the query location.

At the end, we are also describing the output of our function by using the OpenApiResponseWithBody and OpenApiResponseWithoutBody attributes. Specify the status code, the content type and its corresponding object as well as a description.

This is the result of the attribution shown above:

Swagger-UI-Sample-Post

Conclusion

By investing some time into attributing all your functions, you will have a fully blown API documentation ready for yourself and your API consumers. I recommend studying the samples found in the GitHub repo, which helped me a lot to understand all the attributes and how to implement the Swagger page. As always, I hope this post will be helpful for some of you.

In the next post, I will show you how to use an Azure Function as a facade for uploading, deleting and retrieving files from Azure Blob storage.

Until the next post, happy coding, everyone!

Posted by msicc in Azure, Dev Stories, 1 comment
#CASBAN6: How to set up a local Microsoft SQL database on macOS

#CASBAN6: How to set up a local Microsoft SQL database on macOS

Microsoft’s SQL Server cannot be installed directly on macOS, like on Windows machines. Luckily, there is a not so complicated solution using a Docker container – provided by Microsoft themselves.

Install Docker

Obviously, the first step is to download Docker and install it on your Mac. Just head over to the Docker website and download the appropriate version. Install the app by opening the disk image and follow the instructions.

Install SQL Server

After installing the Docker desktop client, head over to the docker hub of Microsoft’s SQL Server. You can choose between SQL Server 2017, 2019 and 2022, with the latter one being preview (as of publishing time of this post). To download the image, we need to open a terminal and download it with the pull command:

sudo docker pull mcr.microsoft.com/mssql/server:2019-latest

I am selecting 2019 here as it is closest to what Azure SQL databases uses as of publishing time of this post.

Create a server instance

Microsoft makes it quite easy to create a server instance, we just need to copy the appropriate run command from the docker hub website. I am using SQL Server Express for my testing purposes:

 docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=thisShouldB3Stronger!' -e 'MSSQL_PID=Express' -p 1433:1433 --name mssql  -d mcr.microsoft.com/mssql/server:2019-latest

Once you run this command without any error, type in docker ps to verify the image is up and running. If all goes well, you should see something like this:

Create a database

Now that we have a running server instance, we can finally create a database for our purposes. We are using this terminal command to achieve our goal:

docker exec -i mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'thisShouldB3Stronger!' -Q 'CREATE DATABASE localDB'

We are logging into our server with this and send the command to create our database. Alternatively, we could already connect using DBeaver(link below) to create the Database. In both cases, we have our local database up and running by now.

Connect

There are several ways to connect to this database. The one we are going to use with Entity Framework Core is the good old connection string:

//template: Data Source=localhost;Initial Catalog=<database>;User ID=sa;Password=<password>

Data Source=localhost;Initial Catalog=localDB;User ID=sa;Password=thisShouldB3Stronger!

If you want to access your database with a GUI, I recommend using either Visual Studio Code with the Azure and SQL workload installed or the Community Edition of DBeaver.

DBeaver Community screenshot

Visual Studio allows connecting on a database level, while DBeaver can be used to connect at server level as well. Both of them also support access to Azure SQL databases, which will be helpful later on.

Conclusion

Microsoft’s SQL Server is not available for macOS. Nonetheless, we are able to quickly set up a Docker container that runs MS SQL and set up a local database for testing. I wrote this post for completeness of the series.

Useful links

Until the next post – happy coding, everyone!

Posted by msicc in Azure, Database, Dev Stories, 3 comments