The title is a lie. You need Swagger to be able to generate your JSON objects, but it’s not what will generate your objects. At Agoda, we use autorest, but our package (autorest) to generate our API calls. That’s because we wanted to use a library called SuperAgent in our client-side code. This generates our API library as well as our objects in TypeScript. It’s super handy when you don’t need to write any API code anymore.
Swagger in .NET
Let’s start at the beginning. How do you get/make your endpoints Swagger? What is Swagger?
Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.
It’s a webpage describing your API that’s usually automatically generated. Now, you should never make this webpage live unless you are a public API. You’re just opening up yourself to a can of worms.
So, how do you make your endpoints Swagger? In .NET we have a very simple library (NuGet package) that you can add. It’s called Swashbuckle, and you can just add it to your project. This will generate the page and JSON file that you need.
Within my team, we don’t make everything visible with Swagger. So, we made our SwaggerVisible attribute. This ensures that we don’t generate unneeded code that would just expose our API and make our JavaScript package bigger.
[AttributeUsage(AttributeTargets.Method)] public sealed class SwaggerVisibleAttribute : Attribute { }
As you can see, this by itself is no help. It’s just a marker. We’ll use this in a filter which you can register in the SwaggerConfig. Like so:
public class SwaggerConfig { ... public static void Register(SwaggerDocsConfig configuration) { ... configuration.OperationFilter<SwaggerVisibilityFilter>(); configuration.DocumentFilter<SwaggerVisibilityFilter>(); } }
Finally, we have a filter that will remove any swagger endpoint that doesn’t have our [SwaggerVisible] attribute.
public class SwaggerVisibilityFilter : IOperationFilter, IDocumentFilter { ... public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer) { foreach (var apiDescription in apiExplorer.ApiDescriptions) { if (apiDescription.ActionDescriptor.GetCustomAttributes<SwaggerVisibleAttribute>().Any()) { continue; } var id = apiDescription.ID; var method = apiDescription.HttpMethod.ToString(); var url = id.Replace(method, ""); var route = "/" + url; swaggerDoc.paths.Remove(route); } } }
It’s now very easy to get your API endpoints generated in the Swagger documentation. All you need to do is add:
[SwaggerVisible] [SwaggerOperation("MyComponent_GetMyModel")] [SwaggerResponse(HttpStatusCode.OK, Type = typeof(MyComponentModel))] public async Task<IHttpActionResult> GetMyModel() { return Ok(new MyComponentModel()); }
Generating the Models
Right, now that you have Swagger set up and functioning, you need to generate the models. We do this client-side with a gulp task. How? We run IISExpress using gulp to spin up an instance of our website with the swagger endpoint. Then we get the .json file and pass that to the autorest.exe. When it succeeds or fails, we then kill the IISExpress process and copy the files over from the temporary directory to our clientside folder.
What have you learned?
Generating code that can take you a while to program (mindlessly) yourself is pretty easy. Maybe at a later point in the year, I’ll explain how we use gulp to run these. You can customise your generator by extending the autorest code. You can expose only some endpoints as Swagger so you don’t add unnecessary code to your project.
Reposted on Medium.
Leave a Reply