{"id":22189975,"url":"https://github.com/fgheysels/apim-versionset-sample","last_synced_at":"2025-08-02T07:33:07.499Z","repository":{"id":229078120,"uuid":"773526042","full_name":"fgheysels/apim-versionset-sample","owner":"fgheysels","description":"A sample on how to apply versioning in ASP.NET and Azure API Management","archived":false,"fork":false,"pushed_at":"2024-03-21T21:25:38.000Z","size":21,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T20:34:16.549Z","etag":null,"topics":["api-versioning","apim","azure-api-management"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fgheysels.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-17T22:16:58.000Z","updated_at":"2024-03-21T21:27:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"7e8cb037-d313-4d44-ba50-c9fad8fbbfb7","html_url":"https://github.com/fgheysels/apim-versionset-sample","commit_stats":null,"previous_names":["fgheysels/apim-versionset-sample"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fgheysels/apim-versionset-sample","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgheysels%2Fapim-versionset-sample","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgheysels%2Fapim-versionset-sample/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgheysels%2Fapim-versionset-sample/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgheysels%2Fapim-versionset-sample/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fgheysels","download_url":"https://codeload.github.com/fgheysels/apim-versionset-sample/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgheysels%2Fapim-versionset-sample/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268348645,"owners_count":24236298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-versioning","apim","azure-api-management"],"created_at":"2024-12-02T11:40:56.109Z","updated_at":"2025-08-02T07:33:07.433Z","avatar_url":"https://github.com/fgheysels.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\n\nThis repository contains samples on how to use versioned ASP.NET API's with Azure API Management VersionSets.\n\nThere are 2 ASP.NET API's present in this repository:\n\n- src/single-api-multiple-versions\n\n  This folder contains an ASP.NET sample API for which one Open API Specification file can be generated per version that is defined in the API. \n\n- src/multiple-apis-multiple-versions\n\n  This folder contains a slightly more complicated ASP.NET sample.  This single ASP.NET API project contains multiple API definitions and each of them is versioned.  In other words, instead of just generating one Open API spec file per version, an Open API spec file is generated for each 'API group' and for each version.\n\n\u003e For detailed information about the source code, please see the readme.md file that is present in each folder.\n\n# Getting started\n\nThis section outlines the steps to deploy the samples to Azure.\nIn a real life scenario, all these steps should be automated via deployment pipelines but that's not the goal of this sample.\n\n## Create an Azure Web App\n\nCreate an Azure Web App.  There are multiple ways to do that; you can do it straightforward via the Azure Portal, by deploying a bicep file that describes your app or via the following Azure CLI commands:\n\n```azcli\naz group create --name apiversionset-test --location \"West Europe\"\naz appservice plan create --name fg-appsvc-test --resource-group apiversionset-test --location \"West Europe\" --sku B1\naz webapp create --name fg-apiversionset-test --resource-group apiversionset-test --plan fg-appsvc-test --runtime dotnet:6\n```\n\n\u003e It's not mandatory to deploy to a Web App to get this sample up and running. The API can be deployed in a Web App for Containers or Container App as well.  For simplicity, an Azure Web App is used.\n\n## Deploy binaries to Azure\n\nThe simplest way to deploy the API binaries to the Azure Web App that has just been created, is by doing this from Visual Studio.NET.  Again, in a real project, deployment should be done via pipelines.\nWhen deploying via the 'Publish' wizard in VS.NET, skip the 'API management' step.  We'll define the API in API Management via a separate command.\n\nWhen publishing the API succeeded, you should be able to see the Swagger UI on the deployed web-app by navigating to `https://\u003cyourwebappname\u003e.azurewebsites.net/api/docs`\n\n## Create an Azure API Management service\n\nSince this sample is about deploying versioned API's in Azure API Management, an API Management instance is required.  Again, there are multiple ways to create an API Management instance.  Be aware that creating an APIM instance takes quite some time.\n\n## Create a VersionSet in APIM\n\nTo deploy a VersionSet to APIM, you can deploy a bicep file that describes the versionset.  \nSee the `apim_versionset.bicep` file that can be found in the `deploy` folder.\n\nDeploy the bicep template using this command:\n\n```azcli\n az deployment group create --name versionset_deploy --resource-group \u003cresourcegroup\u003e --template-file .\\apim_versionset.bicep --parameters apim_name=\u003capim_name\u003e \n```\n\nThis bicep file will define 3 version-sets in the API Management instance:\n\n- cars_api-versionset\n- vessels_api-versionset\n- transport_api-versionset\n\nThe `cars_api-versionset` and `vessels_api-versionset` are used for the `multiple-apis-multiple-versions` sample.\nThe `transport_api-versionset` is used for the `singe-api-multiple-versions` sample.\n\n## Build Open API spec files\n\nWe need to generate the open-api spec for every version of our API.  \n\nIn the `multiple-apis-multiple-versions` sample, the sample Web App has actually 2 different API's defined and there are 2 versions for every API.  This means there will be in fact 4 open API spec files.\nIn the `single-api-multiple-versions` sample, the sample Web App has just 2 different versions of the API.  This means 2 Open API spec files.\n\nBefore we can generate the Open API spec file on the command-line, we first need to install a tool:\n\n```\ndotnet new tool-manifest --force\ndotnet tool install swashbuckle.aspnetcore.cli --version 6.5.0\n```\n\u003e The version that is specified here, must match with the version of the `Swashbuckle.AspnetCore` package that is referenced in the ASP.NET project.\n\nAfterwards, the Open API spec files can be generated.\nFor the `multiple-apis-multiple-versions` sample, execute these commands:\n\n```\ndotnet swagger tofile --output c:/temp/api_cars_v1-openapi.json Fg.Samples.MultipleApiVersions/bin/Debug/net6.0/Fg.Samples.MultipleApiVersions.dll cars_v1\n\ndotnet swagger tofile --output c:/temp/api_cars_v2-openapi.json Fg.Samples.MultipleApiVersions/bin/Debug/net6.0/Fg.Samples.MultipleApiVersions.dll cars_v2\n\ndotnet swagger tofile --output c:/temp/api_vessels_v1-openapi.json Fg.Samples.MultipleApiVersions/bin/Debug/net6.0/Fg.Samples.MultipleApiVersions.dll vessels_v1\n\ndotnet swagger tofile --output c:/temp/api_vessels_v2-openapi.json Fg.Samples.MultipleApiVersions/bin/Debug/net6.0/Fg.Samples.MultipleApiVersions.dll vessels_v2\n```\n\n\u003e Note that the last part of the above command each time represents a 'GroupName' that has been defined in the `ApiExplorerSettings` attribute.\n\n\u003e If the `dotnet swagger` command fails, make sure that you specify the .NET SDK that must be used by creating a `global.json` file that refers to the correct .NET SDK that is installed on your system.\n\u003e List the installed SDK's via `dotnet --list-sdks`\n\u003e Create the global.json file via `dotnet new globaljson --sdk-version \u003cversion\u003e --roll-forward latestMinor`.\n\nFor the `single-api-multiple-versions` sample, execute these commands:\n\n```\ndotnet swagger tofile --output c:/temp/api_transport_v1-openapi.json Fg.Samples.SingleApiMultipleVersions/bin/Debug/net6.0/Fg.Samples.SingleApiMultipleVersions.dll v1\n\ndotnet swagger tofile --output c:/temp/api_transport_v2-openapi.json Fg.Samples.SingleApiMultipleVersions/bin/Debug/net6.0/Fg.Samples.SingleApiMultipleVersions.dll v2\n```\n\n\u003e Note that the last part of the above command just specifies the version.  That's because the version-name defines the 'groupname'.\n\n\u003e If the `dotnet swagger` command fails, make sure that you specify the .NET SDK that must be used by creating a `global.json` file that refers to the correct .NET SDK that is installed on your system.\n\u003e List the installed SDK's via `dotnet --list-sdks`\n\u003e Create the global.json file via `dotnet new globaljson --sdk-version \u003cversion\u003e --roll-forward latestMinor`.\n\n## Import Open API specs in APIM\n\nOnce the Open API specs are created, they can be imported in APIM using the `Import-ApimVersioned-Api.ps1` Powershell script that is found in the `scripts` folder.\n\nThis script will make some changes the the paths that are defined in the Open API specification.  This is necessary because the path that is exposed by APIM already contains the API version information, since the API path must be unique in APIM.\nHowever, if that version information is also present in the paths mentionned in the Open API spec, this results in incorrect API paths. \n\n### multiple-apis-multiple-versions\n\nTo import the Open API spec files for the `multiple-apis-multiple-versions` sample, execute these commands from the `scripts` folder:\n\nFor cars-api v1:\n```powershell\n@apimName = \"\u003cyour-apim-name\u003e\"  \n# The apiId variable corresponds with a part of the versionset-name in the bicep file\n@apiId = \"cars_api\"  \n# The apiPath variable defines the path where the API is found in APIM\n@apiPath = \"cars\"\n# The apiSwaggerPrefix variable defines the part that must be removed from the endpoint-paths in the OpenAPI spec\n@apiSwaggerPrefix = \"/api/v1\"\n# The apiServiceBackendUrl variable defines the address where the implementation of the API can be found\n@apiServiceBackendUrl = \"https://\u003cyourwebappname\u003e.azurewebsites.net\n\n.\\Import-ApimVersioned-Api.ps1 `\n  -Apim_ResourceGroup apiversionset-test `\n  -Apim_Name @apimName `\n  -Api_Id @apiId `\n  -Api_Path @apiPath `\n  -Api_DisplayName \"cars api\" `\n  -Api_Version v1 `\n  -OpenApi_File c:/temp/api_cars_v1-openapi.json `\n  -Api_SwaggerPrefix @apiSwaggerPrefix `\n  -Service_BackendUrl @apiServiceBackendUrl\n```\n\nFor cars-api v2:\n```powershell\n@apimName = \"\u003cyour-apim-name\u003e\"  \n# The apiId variable corresponds with a part of the versionset-name in the bicep file\n@apiId = \"cars_api\"  \n# The apiPath variable defines the path where the API is found in APIM\n@apiPath = \"cars\"\n# The apiSwaggerPrefix variable defines the part that must be removed from the endpoint-paths in the OpenAPI spec\n@apiSwaggerPrefix = \"/api/v2\"\n# The apiServiceBackendUrl variable defines the address where the implementation of the API can be found\n@apiServiceBackendUrl = \"https://\u003cyourwebappname\u003e.azurewebsites.net\n\n.\\Import-ApimVersioned-Api.ps1 `\n  -Apim_ResourceGroup apiversionset-test `\n  -Apim_Name @apimName `\n  -Api_Id @apiId `\n  -Api_Path @apiPath `\n  -Api_DisplayName \"cars api\" `\n  -Api_Version v2 `\n  -OpenApi_File c:/temp/api_cars_v2-openapi.json `\n  -Api_SwaggerPrefix @apiSwaggerPrefix `\n  -Service_BackendUrl @apiServiceBackendUrl\n```\n\nFor vessels-api v1:\n```powershell\n@apimName = \"\u003cyour-apim-name\u003e\"  \n# The apiId variable corresponds with a part of the versionset-name in the bicep file\n@apiId = \"vessels_api\"  \n# The apiPath variable defines the path where the API is found in APIM\n@apiPath = \"vessels\"\n# The apiSwaggerPrefix variable defines the part that must be removed from the endpoint-paths in the OpenAPI spec\n@apiSwaggerPrefix = \"/api/v1\"\n# The apiServiceBackendUrl variable defines the address where the implementation of the API can be found\n@apiServiceBackendUrl = \"https://\u003cyourwebappname\u003e.azurewebsites.net\n\n.\\Import-ApimVersioned-Api.ps1 `\n  -Apim_ResourceGroup apiversionset-test `\n  -Apim_Name @apimName `\n  -Api_Id @apiId `\n  -Api_Path @apiPath `\n  -Api_DisplayName \"vessels api\" `\n  -Api_Version v1 `\n  -OpenApi_File c:/temp/api_vessels_v1-openapi.json `\n  -Api_SwaggerPrefix @apiSwaggerPrefix `\n  -Service_BackendUrl @apiServiceBackendUrl\n```\n\nFor vessels-api v2:\n```powershell\n@apimName = \"\u003cyour-apim-name\u003e\"  \n# The apiId variable corresponds with a part of the versionset-name in the bicep file\n@apiId = \"vessels_api\"  \n# The apiPath variable defines the path where the API is found in APIM\n@apiPath = \"vessels\"\n# The apiSwaggerPrefix variable defines the part that must be removed from the endpoint-paths in the OpenAPI spec\n@apiSwaggerPrefix = \"/api/v2\"\n# The apiServiceBackendUrl variable defines the address where the implementation of the API can be found\n@apiServiceBackendUrl = \"https://\u003cyourwebappname\u003e.azurewebsites.net\n\n.\\Import-ApimVersioned-Api.ps1 `\n  -Apim_ResourceGroup apiversionset-test `\n  -Apim_Name @apimName `\n  -Api_Id @apiId `\n  -Api_Path @apiPath `\n  -Api_DisplayName \"vessels api\" `\n  -Api_Version v2 `\n  -OpenApi_File c:/temp/api_vessels_v2-openapi.json `\n  -Api_SwaggerPrefix @apiSwaggerPrefix `\n  -Service_BackendUrl @apiServiceBackendUrl\n```\n\n### single-api-multiple-versions\n\nTo import the Open API spec files for the `single-api-multiple-versions` sample, execute these commands from the `scripts` folder:\n\nFor v1:\n```powershell\n@apimName = \"\u003cyour-apim-name\u003e\"  \n# The apiId variable corresponds with a part of the versionset-name in the bicep file\n@apiId = \"transport_api\"  \n# The apiPath variable defines the path where the API is found in APIM\n@apiPath = \"transport\"\n# The apiSwaggerPrefix variable defines the part that must be removed from the endpoint-paths in the OpenAPI spec\n@apiSwaggerPrefix = \"/api/v1\"\n# The apiServiceBackendUrl variable defines the address where the implementation of the API can be found\n@apiServiceBackendUrl = \"https://\u003cyourwebappname\u003e.azurewebsites.net\n\n.\\Import-ApimVersioned-Api.ps1 `\n  -Apim_ResourceGroup apiversionset-test `\n  -Apim_Name @apimName `\n  -Api_Id @apiId `\n  -Api_Path @apiPath `\n  -Api_DisplayName \"transport api\" `\n  -Api_Version v1 `\n  -OpenApi_File c:/temp/api_transport_v1-openapi.json `\n  -Api_SwaggerPrefix @apiSwaggerPrefix `\n  -Service_BackendUrl @apiServiceBackendUrl\n```\n\nFor v2:\n```powershell\n@apimName = \"\u003cyour-apim-name\u003e\"  \n# The apiId variable corresponds with a part of the versionset-name in the bicep file\n@apiId = \"transport_api\"  \n# The apiPath variable defines the path where the API is found in APIM\n@apiPath = \"transport\"\n# The apiSwaggerPrefix variable defines the part that must be removed from the endpoint-paths in the OpenAPI spec\n@apiSwaggerPrefix = \"/api/v2\"\n# The apiServiceBackendUrl variable defines the address where the implementation of the API can be found\n@apiServiceBackendUrl = \"https://\u003cyourwebappname\u003e.azurewebsites.net\n\n.\\Import-ApimVersioned-Api.ps1 `\n  -Apim_ResourceGroup apiversionset-test `\n  -Apim_Name @apimName `\n  -Api_Id @apiId `\n  -Api_Path @apiPath `\n  -Api_DisplayName \"transport api\" `\n  -Api_Version v2 `\n  -OpenApi_File c:/temp/api_transport_v2-openapi.json `\n  -Api_SwaggerPrefix @apiSwaggerPrefix `\n  -Service_BackendUrl @apiServiceBackendUrl\n  ```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffgheysels%2Fapim-versionset-sample","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffgheysels%2Fapim-versionset-sample","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffgheysels%2Fapim-versionset-sample/lists"}