Creating a web API means making a promise about the shape of the data exchanged between the API and its consumers. While behavioral aspects are also important, they often require more complex testing strategies, such as integration tests. When it comes to the contract, however, we can leverage tools to ensure that the API adheres to the expected standards, does not break existing consumers, and remains stable over time.
Maintaining API contracts is even more critical when multiple services interact with one another. This is the case at Workleap, where we use a mix of external and internal services to build our products. To provide stability as our HTTP REST APIs evolve, we have established a set of standards, practices, and tools that guarantee API quality and consistency. Everything is fully automated and integrates seamlessly into our teams’ development workflow, both on local machines and in CI environments.
The tooling we built relies on well‑known, open‑source technologies that are widely adopted in the industry. We use OpenAPI to describe our APIs, Spectral to validate the descriptions, oasdiff to detect potential breaking changes, and either Kiota or openapi‑generator to generate clients automatically.
That is a lot of tools to manage, and a major challenge was ensuring they are easy for developers to use without complex configuration or deep domain knowledge. Everything had to be integrated into the development flow so that developers could stay focused on delivering value instead of wrestling with new technical details. Consistency across departments and teams was also an important factor. To achieve this, we created Workleap.OpenApi.MSBuild, a wrapper that embeds these tools into the build process of our ASP.NET Core projects.
Generating the OpenAPI specification
First, we believe that to make API contracts first‑class citizens, they must be treated like code. That means they should be versioned, tested, and maintained just like the rest of the application code. At build time, the API contract must be generated, validated, and compared with the previous version to detect breaking changes.
To automate this, we needed a way to integrate into the .NET build process. Enter Workleap.OpenApi.MSBuild
, an MSBuild task that runs automatically during the build of ASP.NETÂ Core projects. The only requirement is to install the NuGet package.
Normally, the usual ASP.NETÂ Core OpenAPI tooling exposes an endpoint /swagger/v1/swagger.json
containing the API description. As mentioned earlier, we want this description to be part of the codebase, not just available at runtime.
Therefore, Workleap.OpenApi.MSBuild
automatically downloads Swashbuckle.AspNetCore.Cli, a CLI that extracts an OpenAPI specification from an ASP.NETÂ Core project. The task downloads the CLI efficiently and reliably, then generates the specification in the project’s root directory. When a developer changes an API contract, the modified file appears in source control and must be reviewed in the pull request.
To ensure the OpenAPI file is always up to date, Workleap.OpenApi.MSBuild
performs the same generation step in CI and raises an error if the generated specification differs from the committed one. This guarantees that contract changes are always intentional and validated by developers.
In short, developers are not forced to maintain the OpenAPI file manually. They can update their C# code and continue to use familiar ASP.NETÂ Core or Swashbuckle annotations such as [HttpGet]
, [EndpointSummary]
, [Consumes]
, and [Tags]
.
Validating the OpenAPI specification
Having an OpenAPI specification is great, but it must also be valid and comply with company standards and guidelines. For this, we use Spectral, which is also adopted by companies like Adidas, Microsoft, Box, and DigitalOcean.
Spectral is a linter for OpenAPI specifications and allows us to define custom rules. A few examples of the rules we have defined:
- Every object property must have a defined type.
- Operations with a body must specify an allowed
content‑type
. - Each operation must have an operation ID.
- Every operation must return at least one
2xx
or3xx
status code.
To enforce these rules at build time, Workleap.OpenApi.MSBuild
automatically downloads Spectral and runs it against the generated specification. In a local development environment, violations are reported as warnings; in CI, they are treated as errors, causing the build to fail. The issues are highlighted in the logs, and a full report is attached to the workflow run.
Detecting breaking changes
Introducing breaking changes is sometimes unavoidable as an API evolves, but the intent must be explicit and clearly communicated. During refactoring, developers might rename a property, change its type, or modify an object’s structure. While additions are usually safe, modifications or removals can cause issues. Developers need to be aware of these changes.
To automate this, we integrated oasdiff, a CLI that compares two OpenAPI specifications and reports differences according to a predefined policy. For example, we configure oasdiff
to ignore changes to descriptions, examples, titles, and summaries, because altering them does not affect API consumers.
During the build, Workleap.OpenApi.MSBuild
runs oasdiff
to compare the generated specification with the committed version. Because breaking changes can be intentional, validation does not block the build or the completion of a pull request check. The oasdiff
output is attached to the workflow run, and developers are encouraged to review and understand the changes during the pull request review.
Performance considerations
When a development tool is used frequently, slow performance quickly becomes frustrating. We therefore paid special attention to the performance of Workleap.OpenApi.MSBuild
, which sits at the heart of the build process for most of our ASP.NETÂ Core services.
Fast execution, robust error handling, and resilience are crucial for a smooth developer experience. For example, Workleap.OpenApi.MSBuild
downloads each required tool only once and includes a retry policy. Once cached, the impact on build time drops significantly. Even on the first build of a new service, the overhead is under five seconds with a decent internet connection, which is acceptable for most developers. After Swashbuckle.AspNetCore.Cli
, Spectral
, and oasdiff
are cached, the impact is reduced to less than one second.
A customizable golden path
Although we believe the defaults of Workleap.OpenApi.MSBuild
suit most use cases, we also provide configuration options for teams that need to customize its behavior:
- Generate multiple OpenAPI specifications for the same project, for example, for versioned APIs.
- Override the Spectral ruleset URL used for validation.
- Change the location of downloaded or generated intermediate files.
- Disable CI errors, which is useful for progressively adopting the tooling in existing projects.
- Skip specification generation while still running validation, for teams that prefer to maintain contracts manually.
Conclusion
Workleap.OpenApi.MSBuild
saves us significant time and effort when creating and maintaining our web services. It ensures that our APIs comply with company standards and guidelines while delivering a seamless development experience. By automating the generation and validation of OpenAPI specifications, we have improved API quality, reduced the risk of breaking changes, and strengthened collaboration across teams.
Photo of our office in Montréal by Claude-Simon Langlois