Building RESTful APIs is a common activity at endjin. If you've seen our API Maturity Matrix, you'll realise that we spend quite a lot of time thinking about the strategy, governance, legal, commercial, and operational side of building APIs along with the standard concerns of design, development, quality, infrastructure and support.
One of the most exciting areas of the REST ecosystem is the OpenAPI initiative (formerly known as Swagger) which is creating an interoperability and tooling ecosystem that WSDL promised over a decade ago, but never really managed to achieve. OpenAPI is used throughout Azure, with support in Functions, LogicApps and API Management.
Darrel Miller, Senior Software Development Engineer on the Azure API Management Team, is also a Member of OAI Technical Steering Committee. I first became aware of Darrel in 2010, on the project that would lead to the creation of endjin; building a RESTful trading platform for a bank. Matthew & I spent a lot of time thinking about how Hypermedia (or HATEOAS) could be applied to problem domain. Darrel's blog post on Rest Agents sparked a number of discussions that evolved into architectural patterns that we still use today.
Matthew & I were very fortunate to spend an hour talking to Darrel a couple of weeks ago about our plans to build some APIs as we wanted to get a better feel for the Azure API Management Roadmap to make sure that our efforts aligned with that of the Product Group. During the conversation we drifted onto the subject of OpenAPI and Darrel told us about his efforts to produce the OpenAPI.NET SDK; a useful object model for OpenAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.
I had a lightbulb moment.
I had spent the past few weeks experimenting with Azure Functions and APIM and was getting a little frustrated trying to sketch out an architecture for how I'd like to build scalable APIs which expose OpenAPI document which can be imported into APIM. In the past I've used Swashbuckle to define my Swagger documents in ASP.NET, but with Functions you can either let the platform generate your OpenAPI document, or you can handcraft one. If you're going to write your own OpenAPI document YAML is a much easier document format to work with than JSON.
When I learnt from Darrel that the OpenAPI.NET SDK not only supported converting OpenAPI document formats (between YAML <--> JSON) but also gracefully between versions (2.0 <--> 3.0) I wanted to see if I could create a Custom Tool in Visual Studio, in particular a Single-File Generator that could be used to improve the Functions development experience. Within a couple of hours I had a working prototype that contained the following Single-File Generators:
Below you can see it in action; converting a v2.0 JSON based OpenAPI document to a v2.0 YAML based one, and a v2.0 YAML based OpenAPI document to a v2.0 JSON based one.
You can find the code on our fork of the OpenAPI.NET project on GitHub. All the credit should go to Darrel Miller - his work on the OpenAPI.NET SDK make this very simple to implement.
One caveat is that although this works perfectly well for "classic" Visual Studio projects, I have been unable to get the Single-File Generators to work in new Common Project System projects. If you can figure out how, let me know!
UPDATE 28/04/2018: Thanks to the efforts of the SpecFlow team, I've managed to use their
CodeGeneratorRegistrationWithFileExtensionAttribute approach for registering SingleFileGenerators against file types which seems to work with classic and Common Project System (CPS) based projects. W00t!
Once .NET Core 2.1 is GA I may also convert the above sample into a Global Tool.