Doing Runtime Changes

This how-to guide introduces the runtime change support of API Framework. cURL is used to add APIs and endpoints runtime. APIs are added from Nuget.org.

Introduction

This how-to guide introduces the following concepts of using API Framework to make runtime changes:

  • Adding new APIs from Nuget.org
  • Adding new Endpoints

This how-to guide uses the built-in Admin APIs for the functionality. The syntax for adding the APIs and Endpoints using cURL is show in most of the cases.

After creating the backend shown in this sample, we will have a system which starts without any functionality. The functionality (the APIs and the endpoints) is then added runtime. The system ends up with multiple different endpoints, providing access for example to SQL Server and to PetStore's OpenAPI.

Creating the project

Api Framework can be installed into an existing ASP.NET Core app. It works together with Controllers and Actions. For a new backend, Web Api template is a good starting point. ConfigureServices is used to add Api Framework into app.

This guide used the ASP.NET Core Web Application and its API template as the starting point:

Please note: API Framework currently target the LTS version of .NET Core, meaning .NET Core 3.1. Please select that version as the SDK:

This guide uses API Framework's Starter Kit. For an explanation of the differences between Weikio.ApiFramework.Core, Weikio.ApiFramework.AspNetCore and Weikio.ApiFramework.AspNetCoreStarterKit, please see the FAQ.

Starter Kit is available as a Nuget package:

Nuget Version

Start by installing the package and then adding API Framework into your application using ConfigureServices in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddApiFrameworkStarterKit();
}

AddApiFrameworkStarterKit is available from namespace Weikio.ApiFramework.AspNetCore.StarterKit:

using Weikio.ApiFramework.AspNetCore.StarterKit;

As explained in FAQ, the Starter Kit installs NSwag. If you now start the application and navigate to /swagger, you should see the Swagger UI and three different documents: Api, Admin and All:

The Admin Tools

The API Framework starter kit contains a package called Weikio.ApiFramework.Admin. This package adds admin endpoints into your API Framework application, providing the following functionality:

  • API: Get current APIs (the catalog of APIs) and add API from Nuget
  • Endpoints: Get current endpoints, Create a new endpoint, Initialize a new endpoint
  • Status: Get full status of the API Framework: API Catalog, Endpoints

In the next steps we use this endpoints to add new APIs and endpoints runtime.

Adding an API runtime using Nuget

One of the key benefits of API Framework is reusability with the idea of "build once, share with Nuget". In this part of the how-to guide we will add three different Nuget packages which each provide one or many APIs.

Note: API Framework's Admin APIs don't provide persistance.

At this point the backend doesn't contain any APIs. This can be confirmed by running the /admin/api/apis:

First, we will add the Weikio.ApiFramework.Samples.PluginLibrary which contains a collection of example APIs. We need to provide the package name and the version for the PUT admin/api/apis:

curl -X PUT "https://localhost:5001/admin/api/apis?packageName=Weikio.ApiFramework.Samples.PluginLibrary&version=1.0.0-alpha.0.85"

Now when we query the apis, we can see we have many available:

curl -X GET "https://localhost:5001/admin/api/apis"
[
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldApi",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  },
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldComplexConfigurationApi",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  },
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldConfigurationApi",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  },
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldMultipleApi",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  },
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldParameterApi",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  },
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldParameterPostApi",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  },
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldPostApi",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  },
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary.MultiHelloWorldApi",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  },
  {
    "name": "Weikio.ApiFramework.Samples.PluginLibrary",
    "version": {
      "major": 1,
      "minor": 0,
      "build": 0,
      "revision": 0,
      "majorRevision": 0,
      "minorRevision": 0
    },
    "description": "Sample Plugin Library for Api Framework for ASP.NET Core. Api Framework gives you powerful and dynamic tools for easily building Open Api based endpoints.",
    "productVersion": "1.0.0-alpha.0.85"
  }
]

Let's also add the SQL Server and OpenAPI plugins, used in the previous how-to guide:

curl -X PUT "https://localhost:5001/admin/api/apis?packageName=Weikio.ApiFramework.Plugins.SqlServer&version=1.0.0-alpha.0.8"
curl -X PUT "https://localhost:5001/admin/api/apis?packageName=Weikio.ApiFramework.Plugins.OpenApi&version=1.0.0-alpha.0.23"

Now that we have a good collection of APIs available, the next step is to create endpoints based on these APIs.

Creating an Endpoint runtime

The endpoints can be created using the Admin's endpoint functionality. Creating an endpoint happens in two phases:

  1. Endpoint is created. Endpoint route, API and configuration is provided as input.
  2. Endpoint is initialized. This may take from 0 seconds to 3 minutes based on the API.

To create an Endpoint, one can use the /admin/api/Endpoints. Let's try creating an endpoint using the Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldApi. This API doesn't take configuration so we need to provide only the API name, API version and the endpoint's route:

{
	"Api": {
		"Name": "Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldApi",
		"Version": "1.0.0.0"
	},
	"Route": "/hello"
}

Or in Curl-format:

curl -X POST "https://localhost:5001/admin/api/Endpoints" -H  "accept: application/octet-stream" -H  "Content-Type: application/json" -d "{\"Api\":{\"Name\":\"Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldApi\",\"Version\":\"1.0.0.0\"},\"Route\":\"/hello\"}"

Now if we check the status of the system, we can see that there is one new endpoint, though it is not initialized. So calling /api/hello will result in 404 and also the OpenAPI documentation is still missing this endpoint:

And the status:

To get the endpoint up and running, it must be initialized. Initialization happens through the endpointroute/initialize:

Or in Curl-format:

curl -X POST "https://localhost:5001/admin/api/Endpoints/%2Fhello/initialize" -d ""

Now, if we first check the API Framework status we should see that the endpoint is in "Ready"-status:

Also if we navigate to the Api document we should see our endpoint:

And finally, we should be able to access the endpoint:

We could create multiple endpoints using the same API, though as the API in this case doesn't take any configuration, all the endpoints would end up working identically.

Let us add two more endpoints: One for the SQL Server API and one for the OpenAPI. Both of these take configuration:

curl -X POST "https://localhost:5001/admin/api/Endpoints" -H  "accept: application/octet-stream" -H  "Content-Type: application/json" -d '{\"Api\":{\"Name\":\"Weikio.ApiFramework.Plugins.SqlServer\",\"Version\":\"1.1.0.0\"},\"JsonConfiguration\":{\"ConnectionString\":\"Server=tcp:adafydevtestdb001.database.windows.net,1433;User ID=docs;Password=3h1@*6PXrldU4F95;Integrated Security=false;Initial Catalog=adafyweikiodevtestdb001;\"},\"Route\":\"/adventure\"}' -k

curl -X POST "https://localhost:5001/admin/api/Endpoints" -H  "accept: application/octet-stream" -H  "Content-Type: application/json" -d '{\"Api\":{\"Name\":\"Weikio.ApiFramework.Plugins.OpenApi\",\"Version\":\"1.0.0.0\"},\"JsonConfiguration\":{\"SpecificationUrl\":\"https://petstore.swagger.io/v2/swagger.json\"},\"Route\":\"/pets\"}' -k

And then initialize them:

curl -X POST "https://localhost:5001/admin/api/Endpoints/%2Fadventure/initialize" -H  "accept: application/octet-stream" -d "{}"

curl -X POST "https://localhost:5001/admin/api/Endpoints/%2Fpets/initialize" -H  "accept: application/octet-stream" -d "{}"

Now we should have our backend up and running with three different endpoints:

Here's how to completely script this using curl:

curl -X PUT "https://localhost:5001/admin/api/apis?packageName=Weikio.ApiFramework.Plugins.SqlServer&version=1.1.0-alpha.0.8&feedUrl=https%3A%2F%2Fapi.nuget.org%2Fv3%2Findex.json" -H  "accept: application/octet-stream" -k -d '{}'
curl -X PUT "https://localhost:5001/admin/api/apis?packageName=Weikio.apiframework.plugins.openapi&version=1.0.0-alpha.0.23&feedUrl=https%3A%2F%2Fapi.nuget.org%2Fv3%2Findex.json" -H  "accept: application/octet-stream" -k -d '{}'
curl -X PUT "https://localhost:5001/admin/api/apis?packageName=Weikio.ApiFramework.Samples.PluginLibrary&version=1.0.0-alpha.0.85&feedUrl=https%3A%2F%2Fapi.nuget.org%2Fv3%2Findex.json" -H  "accept: application/octet-stream" -k -d '{}'
curl -X POST "https://localhost:5001/admin/api/Endpoints" -H  "accept: application/octet-stream" -H  "Content-Type: application/json" -d '{\"Api\":{\"Name\":\"Weikio.ApiFramework.Plugins.SqlServer\",\"Version\":\"1.1.0.0\"},\"JsonConfiguration\":{\"ConnectionString\":\"Server=tcp:adafydevtestdb001.database.windows.net,1433;User ID=docs;Password=3h1@*6PXrldU4F95;Integrated Security=false;Initial Catalog=adafyweikiodevtestdb001;\"},\"Route\":\"/adventure\"}' -k
curl -X POST "https://localhost:5001/admin/api/Endpoints" -H  "accept: application/octet-stream" -H  "Content-Type: application/json" -d '{\"Api\":{\"Name\":\"Weikio.ApiFramework.Plugins.OpenApi\",\"Version\":\"1.0.0.0\"},\"JsonConfiguration\":{\"SpecificationUrl\":\"https://petstore.swagger.io/v2/swagger.json\"},\"Route\":\"/pets\"}' -k
curl -X POST "https://localhost:5001/admin/api/Endpoints" -H  "accept: application/octet-stream" -H  "Content-Type: application/json" -d '{\"Api\":{\"Name\":\"Weikio.ApiFramework.Samples.PluginLibrary.HelloWorldApi\",\"Version\":\"1.0.0.0\"},\"Route\":\"/hello\"}' -k
curl -X POST "https://localhost:5001/admin/api/Endpoints/%2Fadventure/initialize" -H  "accept: application/octet-stream" -d "{}"
curl -X POST "https://localhost:5001/admin/api/Endpoints/%2Fpets/initialize" -H  "accept: application/octet-stream" -d "{}"
curl -X POST "https://localhost:5001/admin/api/Endpoints/%2Fhello/initialize" -H  "accept: application/octet-stream" -d "{}"

Source Code

Source code for this sample is available from GitHub: https://github.com/weikio/ApiFramework.Samples/tree/main/howtos/3_RuntimeChanges

Though note that the code for this sample is quite basic as the endpoints are created runtime.

Summary

This guide introduced the following concepts:

  • Adding a new API using Nuget.org runtime
  • Creating a new Endpoint from an API runtime

API Framework contains admin endpoints which can be used to make runtime changes and to get the current runtime status of the system. With this functionality it is possible to build 24/7 backends where new functionality (APIs) and new endpoints are added when required.