{"id":24506,"date":"2021-02-11T14:14:34","date_gmt":"2021-02-11T21:14:34","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/aspnet\/?p=24506"},"modified":"2021-02-11T14:14:34","modified_gmt":"2021-02-11T21:14:34","slug":"open-source-http-api-packages-and-tools","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/open-source-http-api-packages-and-tools\/","title":{"rendered":"Open-source HTTP API packages and tools"},"content":{"rendered":"<p>We&#8217;re continuing our series on building HTTP APIs with .NET 5. In the previous post, we covered Creating Discoverable HTTP APIs with ASP.NET Core 5 Web API. In this post, we&#8217;ll go further with a look at using open-source HTTP API packages and tools. Let&#8217;s dig in!<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/aspnet\/creating-discoverable-http-apis-with-asp-net-core-5-web-api\">Creating Discoverable HTTP APIs with ASP.NET Core 5 Web API<\/a><\/li>\n<li>Open-source HTTP API packages and tools (this post)<\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/aspnet\/generating-http-api-clients-using-visual-studio-connected-services\/\">Generating HTTP API clients using Visual Studio Connected Services<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/aspnet\/app-building-with-azure-api-management-functions-power-apps-and-logic-apps\/\">App Building with Azure API Management, Power Apps, and Logic Apps<\/a><\/li>\n<\/ul>\n<h2>Open-source tools, packages, and extensions for HTTP API developers<\/h2>\n<p>This post will cover a variety of things any .NET developer who plans on building HTTP APIs will want in their toolchain or dependency list. We&#8217;ll show you some new and exciting frameworks coming up that are built atop ASP.NET Core web API and hopefully make the craft of building and testing HTTP APIs with .NET easier. There are so many opportunities in the form of NuGet packages, Visual Studio and Visual Studio Code extensions, and independently-maintained frameworks, we can&#8217;t capture them all in one post. Feel free to use the comments below to share some of your favorite web API tools and packages.<\/p>\n<h2>NuGet packages for building .NET HTTP APIs<\/h2>\n<p>This first section will cover some of the most important NuGet packages in your HTTP API toolchain. Many of these tools are used in our own pet projects and workshops. Some of the tools appear in our templates and tools as dependencies.<\/p>\n<h3>OpenAPI generation<\/h3>\n<p>In the <a href=\"https:\/\/devblogs.microsoft.com\/aspnet\/creating-discoverable-http-apis-with-asp-net-core-5-web-api\">first article in this series<\/a>, we touched on the idea of creating discoverable APIs. Since the term <em>discoverable<\/em> in API lingo is associated with <em>service discovery<\/em>, maybe the better term for the article would have been <strong>well-described<\/strong>. By describing APIs using the OpenAPI specification (formerly Swagger specification), developers get all kinds of code-generation and integration opportunities. We&#8217;ll touch on those later in the series. The point is that <strong>OpenAPI generation is important<\/strong> and should be something you&#8217;re at least generating, if not designing.<\/p>\n<p>Some consider the idea of generating OpenAPI specifications from code an &#8220;inside-out&#8221; approach, and design tools are a topic we&#8217;ll touch on later. But when building quickly, or maintaining a level of &#8220;well-designedness&#8221; whilst still generating the specification from code, you have two main options with traditional ASP.NET and ASP.NET Core web API: <a href=\"https:\/\/github.com\/RicoSuter\/NSwag\">NSwag<\/a> and <a href=\"https:\/\/github.com\/domaindrivendev\/Swashbuckle.AspNetCore\">Swashbuckle<\/a>. Both of these projects are maintained almost entirely by single individuals with small teams of passionate contributors, and both have had a signifcant impact in the .NET HTTP API ecosystem.<\/p>\n<h3>NSwag<\/h3>\n<p>Whilst NSwag&#8217;s most popular usage scenario is OpenAPI specification generation from web API controller projects via <a href=\"https:\/\/www.nuget.org\/packages\/NSwag.AspNetCore\/\">NSwag.AspNetCore<\/a>, the project&#8217;s team has contributed all manner of other contributions:<\/p>\n<ul>\n<li>Code generation to generate <a href=\"https:\/\/github.com\/RicoSuter\/NSwag\/wiki\/CSharpClientGenerator\">strongly-typed C# HTTP API clients<\/a>, <a href=\"https:\/\/github.com\/RicoSuter\/NSwag\/wiki\/CSharpControllerGenerator\">Web API Controllers from OpenAPI<\/a>, and <a href=\"https:\/\/github.com\/RicoSuter\/NSwag\/wiki\/TypeScriptClientGenerator\">TypeScript clients<\/a>.<\/li>\n<li>Build OpenAPI specifications from <a href=\"https:\/\/github.com\/RicoSuter\/NSwag\/wiki\/WebApiToOpenApiCommand\">existing .NET assemblies<\/a>. For example, binaries, not source. <\/li>\n<li>A desktop app, <a href=\"https:\/\/github.com\/RicoSuter\/NSwag\/wiki\/NSwagStudio\">NSwagStudio<\/a>, that allows you to utilize most of the NSwag features without having to write code.<\/li>\n<\/ul>\n<p>NSwag&#8217;s rich ecosystem of NuGet packages is used by the Visual Studio Connected Services &#8220;OpenAPI SDK Generation&#8221; feature, which we&#8217;ll explore in more detail in the third article in this series. NSwag&#8217;s code generation tools produce quality, idiomatic C# client code for <strong>well-described<\/strong> APIs.<\/p>\n<h3>Swashbuckle<\/h3>\n<p><a href=\"https:\/\/github.com\/domaindrivendev\/Swashbuckle.AspNetCore\">Swashbuckle<\/a> has been used by millions of web API projects built by customers and internal teams. It was also adopted by the <a href=\"https:\/\/swagger.io\/tools\/swagger-codegen\/\">Swagger Codegen<\/a> team in their templates, which are used by many API ecosystem products. Given the presence Swashbuckle has in the web API space, it has been used in our templates since the .NET 5 RC release. It is on-by-default but can be toggled in the new project dialog in Visual Studio (or using the <code>--no-openapi<\/code> option with the .NET CLI&#8217;s <code>dotnet new webapi<\/code> command).<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/openapi-checkbox.png\" alt=\"OpenAPI Checkbox\" \/><\/p>\n<p>Swashbuckle also has a .NET CLI tool, <a href=\"https:\/\/www.nuget.org\/packages\/Swashbuckle.AspNetCore.Cli\/\">Swashbuckle.CLI<\/a>, that can be used to generate OpenAPI specifications during your MSBuild or <code>dotnet publish<\/code> commands. The <a href=\"https:\/\/github.com\/bradygaster\/Contoso.Online.Orders\">sample project<\/a> has an <a href=\"https:\/\/github.com\/bradygaster\/Contoso.Online.Orders\/blob\/main\/ContosoOnlineOrders.Api\/ContosoOnlineOrders.Api.csproj\">example C# project file<\/a> showing how to use the Swashbuckle CLI during a build process.<\/p>\n<h3>Microsoft.OpenAPI<\/h3>\n<p>No list of important NuGet packages for the HTTP API developer ecosystem would be complete without <a href=\"https:\/\/github.com\/microsoft\/OpenAPI.NET\">Microsoft.OpenAPI<\/a>. A dependency of most of the OpenAPI-supporting projects in the .NET and Azure community, this package is responsible for a variety of features:<\/p>\n<ul>\n<li>Translating between versions of Swagger and OpenAPI, YAML, or JSON flavors.<\/li>\n<li>Provides a single shared object model in .NET for OpenAPI descriptions.<\/li>\n<li>Reading and writing OpenAPI descriptions.<\/li>\n<\/ul>\n<p>If you&#8217;re building an app or NuGet package for .NET HTTP API developers using OpenAPI, you&#8217;ll probably want to take a look at <code>Microsoft.OpenAPI<\/code>. It will ease much of the burden of parsing or writing OpenAPI documents and descriptions.<\/p>\n<h3>ASP.NET API Versioning<\/h3>\n<p>One of the most important concepts in building APIs that no one tells you about until too late is that, at some point, you&#8217;ll need to release breaking changes in APIs many of your customers continue to use. Versioning APIs is complex, and it doesn&#8217;t help when you have to do everything manually, so having a fantastic (and used by so many customers and internal teams I&#8217;d argue <em>prolific<\/em>), is <a href=\"https:\/\/github.com\/microsoft\/aspnet-api-versioning\">ASP.NET API Versioning<\/a>. Scott Hanselman <a href=\"https:\/\/www.hanselman.com\/blog\/aspnet-core-restful-web-api-versioning-made-easy\">wrote about API Versioning<\/a> way back in 2016, and since then it has become an important asset in web API development.<\/p>\n<p>API Versioning enables you to decorate your API controllers with additional attributes that enable the API versions in which the controller&#8217;s operations should appear.<\/p>\n<pre><code class=\"csharp\">[ApiVersion(\"1.0\")]\n[ApiVersion(\"1.1\")]\npublic class ShopController : ControllerBase\n{\n}\n<\/code><\/pre>\n<p>Controller action methods can be decorated as well, to identify the versions in which they map or &#8220;appear.&#8221; In the <a href=\"\">sample code<\/a> complementing this series, you&#8217;ll see the <code>GetProducts<\/code> method and the <code>GetProductsPage<\/code> method, added in version 1.1 of the API.<\/p>\n<pre><code class=\"csharp\">[HttpGet(\"\/products\", Name = nameof(GetProducts))]\npublic async Task&lt;ActionResult&lt;IEnumerable&lt;Product&gt;&gt;&gt; GetProducts()\n{\n    return await Task.FromResult(Ok(StoreServices.GetProducts()));\n}\n\n[HttpGet(\"\/products\/page\/{page}\", Name = nameof(GetProductsPage))]\n[MapToApiVersion(\"1.1\")]\npublic async Task&lt;ActionResult&lt;IEnumerable&lt;Product&gt;&gt;&gt; GetProductsPage([FromRoute] int page = 0)\n{\n    var pageSize = 5;\n    var productsPage = StoreServices.GetProducts().Skip(page * pageSize).Take(pageSize);\n    return await Task.FromResult(Ok(productsPage));\n}\n<\/code><\/pre>\n<p>API Versioning has many samples and Wiki articles on how to get started. One of these shows how to use <a href=\"https:\/\/github.com\/microsoft\/aspnet-api-versioning\/tree\/master\/samples\/aspnetcore\/SwaggerSample\">API Versioning and Swashbuckle together<\/a>, which I&#8217;ve borrowed for the sample project accompanying this blog series. By adding a small amount of additional code to <code>Startup.cs<\/code> and by using a few infrastructure classes to iterate over the various API versions in your project, you can enlist API Versioning to help you draw out independent Swagger UI pages for multiple versions of your APIs. This changes the Swagger UI to show a drop-down menu containing the API versions in your project.<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/swagger-ui-10.png\" alt=\"Swagger UI with drop-down versioning selector\" \/><\/p>\n<p>Note the <code>Shop<\/code> operations\u2014there are 3 in the <code>1.0<\/code> version of the API. But once we change the version menu to see the <code>1.1<\/code>, the new <code>GetProductsPage<\/code> operation only available in the <code>1.1<\/code> API version appears.<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/swagger-ui-11.png\" alt=\"Swagger UI showing version 1.1\" \/><\/p>\n<p>The code generation tools in Visual Studio Connected Services OpenAPI SDK generation features are aware of the <code>api-version<\/code> querystring that the API will expect now. When using API Versioning, the generated code adds a parameter to capture the API version string, too. This can be defaulted so that API Versioning will automatically pick the intended version, but in this case I&#8217;m implying a more opinionated approach with my client.<\/p>\n<pre><code class=\"csharp\">\/\/ create a product\napiClient.CreateProductAsync(\"1.1\", \n  new CreateProductRequest\n  {\n      Id = 1000,\n      InventoryCount = 0,\n      Name = \"Mild Salsa\"\n  });\n\n\/\/ update a product's inventory\napiClient.UpdateProductInventoryAsync(1000, \"1.1\", \n  new InventoryUpdateRequest\n  {\n      CountToAdd = 50,\n      ProductId = 1000\n  });\n<\/code><\/pre>\n<h3>Refit<\/h3>\n<p><a href=\"https:\/\/www.nuget.org\/packages\/Refit\/\">Refit<\/a> is the automatic type-safe REST library for .NET. It turns your interface into a live REST client. Consider the <code>IContosoOnlineOrdersApiClient<\/code> example interface below, which would expose method signatures for calling a few of the API methods.<\/p>\n<pre><code class=\"csharp\">public interface IContosoOnlineOrdersApiClient\n{\n    [Get(\"\/products\")]\n    Task&lt;IEnumerable&lt;Product&gt;&gt; GetProducts();\n\n    [Post(\"\/products\")]\n    Task CreateProduct([Body] CreateProductRequest request);\n}\n<\/code><\/pre>\n<p>Refit&#8217;s <code>RestService<\/code> class generates an implementation of <code>IContosoOnlineOrdersApiClient<\/code> that uses <code>HttpClient<\/code> to make its calls. In the example solution, there&#8217;s a Refit client project demonstrating how to use a Refit client to access a back-end HTTP API.<\/p>\n<pre><code class=\"csharp\">var client = RestService.For&lt;IContosoOnlineOrdersApiClient&gt;(\"http:\/\/localhost:5000\");\nvar products = await client.GetProducts();\nawait client.CreateProduct(new CreateProductRequest\n{\n  Id = 1001,\n  InventoryCount = 10,\n  Name = \"Taco Shells\"\n});\nproducts = await client.GetProducts();\n<\/code><\/pre>\n<p>If you&#8217;re hand-rolling your own client code for back-end APIs, Refit is a great option you should investigate. Refit enables a simplified approach to creating clients for HTTP APIs and abstracts away all of the nuanced <code>HttpClient<\/code> semantics.<\/p>\n<h2>Tools and extensions for designing and testing HTTP APIs<\/h2>\n<p>In addition to these useful NuGet packages, there are a handful of great tools you can use from both the command line and within your favorite IDEs for designing, building, and testing HTTP APIs.<\/p>\n<h3>The HttpRepl<\/h3>\n<p>The <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.dotnet-httprepl\">HttpRepl<\/a> is a .NET CLI Global tool that can be that provides a directory-style way of exploring an HTTP API described by an OpenAPI specification. Once installed, you can use the command <code>httprepl -o &lt;openapi-url&gt;<\/code> to connect to any OpenAPI-described web API project and explore it using familiar commands like <code>ls<\/code> or <code>dir<\/code> and navigating the API&#8217;s structure much like a directory tree.<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/httprepl-e1613077133483.png\" alt=\"HttpRepl\" \/><\/p>\n<p>If you haven&#8217;t tried the HttpRepl, check out the <a href=\"https:\/\/docs.microsoft.com\/aspnet\/core\/web-api\/http-repl\/\">HttpRepl docs<\/a> for more information on the various commands it offers. The docs also show how you can set up the HttpRepl as a &#8220;browser&#8221; so you can &#8220;F5 debug into the HttpRepl&#8221; if you&#8217;re more comfortable in the terminal.<\/p>\n<h3>REST Client for Visual Studio Code<\/h3>\n<p>There are some impressive HTTP API tools that ship as extensions to Visual Studio Code. One of these, <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=humao.rest-client\">REST Client<\/a>, offers in-IDE HTTP API request testing. By creating <code>.http<\/code> files into which you write your own request tests, you can trigger REST Client to activate &#8220;Send Request&#8221; links above each HTTP request you intend on testing.<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/restclient.png\" alt=\"REST Client\" \/><\/p>\n<h3>Network Console<\/h3>\n<p>Microsoft Edge DevTools recently included an <a href=\"https:\/\/docs.microsoft.com\/microsoft-edge\/devtools-guide-chromium\/experimental-features\/\">experimental feature<\/a> named <strong>Network Console<\/strong>. Network Console offers Edge users in-browser HTTP API testing features. To try it out you&#8217;ll first need to enable the Network Console in Edge DevTools experimental features.<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/enable-nc-e1613077173259.png\" alt=\"Edge DevTools Network Console\" \/><\/p>\n<p>Once Network Console is enabled, you can right-click any previously made HTTP request and select the <strong>Edit and Resend<\/strong> menu item.<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/edit-and-resend.png\" alt=\"Edit and Reply\" \/><\/p>\n<p>Clicking Edit and Resend will open an HTTP API testing tool, right inside of Edge. So, when you&#8217;re building web apps that make HTTP API calls back to the server, or when you&#8217;re building Blazor apps that do this sort of thing, you can resend the messages and analyze the API behavior without leaving your browser.<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/network-console.png\" alt=\"Network Console\" \/><\/p>\n<h3>OpenAPI Editor<\/h3>\n<p>Editing or manually-creating OpenAPI documents can be daunting, so it helps when you can install a great editor and OpenAPI design extension right into Visual Studio Code. <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=42Crunch.vscode-openapi\">OpenAPI Editor<\/a> provides just such functionality. This extension includes features like:<\/p>\n<ul>\n<li>Swagger UI and ReDoc preview<\/li>\n<li>IntelliSense for when you&#8217;re manually editing the JSON\/YAML content for your OpenAPI specification<\/li>\n<li>Navigation in the form of tool windows inside of Visual Studio Code.<\/li>\n<\/ul>\n<p>I can use the tool window to find an individual operation in my HTTP API rather than scrolling through a huge JSON file.<\/p>\n<p><img decoding=\"async\" src=\"\/aspnet\/wp-content\/uploads\/sites\/16\/2021\/02\/42crunch-openapi.png\" alt=\"OpenAPI Editor\" \/><\/p>\n<h3>Frameworks built atop ASP.NET Core or Web API<\/h3>\n<p>With such a vibrant community, it&#8217;s common for open-source contributors to extend the ASP.NET framework with their own inventions, or even to push web API into new and exciting directions. Two recent projects are great examples of how the community is taking ASP.NET and web API in new directions.<\/p>\n<h3>API Endpoints<\/h3>\n<p>Steve Smith has started working on an exciting project known as <a href=\"https:\/\/github.com\/ardalis\/ApiEndpoints?WT.mc_id=dotnet-13135-bradyg\">API Endpoints<\/a> that builds on top of ASP.NET Core web API. The project has a mission of abstracting away the need for a developer to think about the concept of a controller to build their HTTP API. Steve wrote about <a href=\"https:\/\/ardalis.com\/mvc-controllers-are-dinosaurs-embrace-api-endpoints\/\">API Endpoints on his blog<\/a>, describing his aspirations and the direction of the project. Essentially, API Endpoints abstracts the controller away so you&#8217;re left with a bit less code to author, whilst still being able to use the full feature-set provided by ASP.NET Core MVC Action Result classes.<\/p>\n<pre><code class=\"csharp\">[HttpPost(\"\/authors\")]\n[SwaggerOperation(\n    Summary = \"Creates a new Author\",\n    Description = \"Creates a new Author\",\n    OperationId = \"Author.Create\",\n    Tags = new[] { \"AuthorEndpoint\" })\n]\npublic override async Task&lt;ActionResult&lt;CreateAuthorResult&gt;&gt; HandleAsync([FromBody]CreateAuthorCommand request)\n{\n    var author = new Author();\n    _mapper.Map(request, author);\n    await _repository.AddAsync(author);\n\n    var result = _mapper.Map&lt;CreateAuthorResult&gt;(author);\n    return Ok(result);\n}\n<\/code><\/pre>\n<p>Since API Endpoint sits atop web API, you can use Swashbuckle or NSwag, or any other web API extension along with API Endpoints and reap the benefits of the wider web API stack, but taking a more modular approach rather than one based on MVC.<\/p>\n<h3>The Carter Project<\/h3>\n<p>The Carter Community&#8217;s <a href=\"https:\/\/github.com\/CarterCommunity\/Carter\">Carter<\/a> project brings even more modularity to your ASP.NET Core apps. Inspired by the Nancy project, Carter brings an endpoint-centric approach to building HTTP APIs with ASP.NET Core. The syntax for Carter is great for developers who appreciate the endpoint routing approach, and offers a clean set of APIs for getting started quickly.<\/p>\n<pre><code class=\"csharp\">public class HomeModule : CarterModule\n{\n    public HomeModule()\n    {\n        Get(\"\/\", async (req, res) =&gt; await res.WriteAsync(\"Hello from Carter!\"));\n    }\n}\n<\/code><\/pre>\n<p>With numerous samples and docs, the project is easy to learn and to experiment with, and offers an interesting spin on building HTTP apps. OpenAPI is built into Carter by default, so endpoints you create can be output to OpenAPI specifications automatically. Carter can also be intertwined with traditional web API and ASP.NET Core app structure, so you can use Carter along with familiar ASP.NET Core middleware and services.<\/p>\n<h2>Summary<\/h2>\n<p>APIs are about making our apps more open to change and to interaction with other APIs, apps, and services. There are many open-source and even more third-party tools, services, and frameworks built atop ASP.NET and ASP.NET Core web API to enable you limitless extension opportunities. The packages and tools listed in this post are just a few of the ones we use in our own projects and experiments, whilst others mark new directions in ASP.NET and our community&#8217;s approach to building software.<\/p>\n<p>We hope this and the other posts in this series bring inspiration and delight to your API development experience. Use the comments below to share other tools, extensions, or packages you feel would augment this post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post covers a variety of things any .NET developer who plans on building HTTP APIs will want in their toolchain or dependency list. We&#8217;ll show you some new and exciting frameworks coming up that are built atop ASP.NET Core web API and hopefully make the craft of building and testing HTTP APIs with .NET easier. There are so many opport<\/p>\n","protected":false},"author":2046,"featured_media":24515,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197,7509],"tags":[32,7230],"class_list":["post-24506","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","category-aspnetcore","tag-asp-net-core","tag-web-api"],"acf":[],"blog_post_summary":"<p>This post covers a variety of things any .NET developer who plans on building HTTP APIs will want in their toolchain or dependency list. We&#8217;ll show you some new and exciting frameworks coming up that are built atop ASP.NET Core web API and hopefully make the craft of building and testing HTTP APIs with .NET easier. There are so many opport<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/24506","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/2046"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=24506"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/24506\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/24515"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=24506"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=24506"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=24506"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}