I still recall the simplicity of standing up a SOAP service and adding a service reference via Visual Studio by simply entering the url to the WSDL – this scenario just worked…. until we moved on. There was a rapid progression away from the overly prescriptive XML based world of SOAP to REST based APIs. This was all well and good but there was no longer a standard approach to documenting these APIS. Enter Swagger, and subsequently OpenAPI, as a way to document REST based APIs. Rather than spend time in this post detailing how you can add some Swagger to your web api (look here if you’re interested), I’m going to focus on consuming a REST based API by first importing its Swagger and using that to generate the code for accessing the API.
One of the most important points to note about this process, is that we’ll be working with a .NET Standard 2.0 class library. This means that the same library can be used across any application you might want to build, whether it be a console application, or a Xamarin.Forms app, or a Uno app (go to https://platform.uno/ to learn more about the Uno Platform).
In fact, to illustrate this point, I have a solution which has both a Uno and a Xamarin.Forms application in it. The solution also has a Data project (just a regular .NET Standard 2.0 library), which is where we’ll be importing the Swagger document. The Data project is referenced by each of the head projects for both Xamarin.Forms and Uno.
The REST service that we’re going to call is one that I setup as part of generating the OCS files for Build 2020 (more details here). The swagger documentation can be found at https://build2020.builttoroam.com/swagger/index.html, which is just a pretty version of the actual Swagger/OpenAPI document that’s located at https://build2020.builttoroam.com/swagger/v1/swagger.json
The process for referencing a REST API that has a Swagger or OpenAPI is now one of the global tools that ships with the dotnet cli. High level documentation for the OpenAPI tool can be found on the Microsoft docs website. We’ll step through the process here as it’s relatively simple.
To start with, we need to make sure that the openapi tool has been installed. This can be done by running the following at a command prompt:
dotnet tool install -g Microsoft.dotnet-openapi
Next, navigate to the folder of the project you want to reference the swagger document and call the openapi command, along with the “add url” parameter (and of course the url of the swagger document).
dotnet openapi add url https://build2020.builttoroam.com/swagger/v1/swagger.json
Returning to Visual Studio we can see that a file, swagger.json, has been added to the Data project.
We’ll add a small snippet of code to call one of the REST APIs.
var client = new swaggerClient("https://build2020.builttoroam.com", new System.Net.Http.HttpClient()); var sessions = await client.SessionsAsync(); System.Diagnostics.Debug.WriteLine(sessions.Count);
This is all well and good but what happens if you want to customize the generated code….oh wait, what….generated code… I forgot to mention, as part of building the Data library, the swagger.json document that was added to your project is converted into a set of classes that make invoking the REST APIs super easy (as you saw above in the code example).
If you press F12 when the cursor is located in swaggerClient class name (or just right-click on the swaggerClient class and select Go To Definition) you’ll be taken to the generated swaggerClient.cs file (in the obj folder). Don’t make changes directly to this file as they will get overwritten the next time you build the Data project.
As I was about to say, there are a couple of ways you can customize the generated code. The first way is to adjust the code generation itself. You can do this by supplying options that configure the way the code generation is done. When the “dotnet openapi” command was invoked earlier, in addition to adding the swagger.json file to the project, an entry was added to the csproj file.
<OpenApiReference Include="swagger.json" SourceUrl="https://build2020.builttoroam.com/swagger/v1/swagger.json" />
The OpenApiReference element in the csproj invokes the code generation during the build process by calling out to the popular NSwag command line tool. As such the options that can be used are the same as for the Nswag tool (A full list of options can be found in the NSwag source code here). For example, let’s ensure an interface is generated for the swaggerClient class, we can set the GenerateClientInterfaces property to true.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="NSwag.ApiDescription.Client" Version="13.0.5" /> </ItemGroup> <ItemGroup> <OpenApiReference Include="swagger.json" SourceUrl="https://build2020.builttoroam.com/swagger/v1/swagger.json"> <Options>/GenerateClientInterfaces:true</Options> </OpenApiReference> </ItemGroup> </Project>
The other way we can extend the swaggerClient class is by adding the implementation of one or more of the partial methods that has been created. Again, if you go to definition on the swaggerClient class, you can see these partial method declarations.
To implement these partial methods, simply add a partial class called swaggerClient to the project, and add the method you want to implement. For example, adding the PrepareRequest method, you can log out the actual url of each API call.
And there you have it, a super simple way to reference a REST API from a .NET Standard library, which can then be used by your Xamarin.Forms, Uno or even a console app.
Big shout out to Rico Suter for the amazing work he’s done with the NSwag library