
The Contract First approach is gaining increasing popularity in software development, particularly in microservice architecture. However, this methodology is not limited to software development—it can also be applied to structuring team interactions. Alexey Kish, a lead developer at Semrush and an expert in microservice system design, discusses the key features, benefits, and practical implementation of the Contract First approach.
Introduction to Contract First
Contract First is an approach to API and software development where a theoretical model (i.e., a contract) is created first, and then the code is written based on this contract, adhering to agreed-upon rules and standards. The alternative is the Code First approach, where code is written first and then used to generate a contract.
In other words, Contract First ensures that all stakeholders agree on how the software should be structured before any development begins. This allows different teams to work on their components independently, guided by the contract. The contract, which defines client and server expectations, can be described using various systems and standards, such as OpenAPI and gRPC. It specifies only the input and output results, leaving the internal implementation up to developers, as long as they meet the contract requirements.
Advantages of the Approach
Stability, Transparency, and Predictability
Each party works within the framework of a predefined contract, ensuring clarity on expected outcomes. The contract defines how system components interact, what data types are used, and what constraints exist, leading to a predictable final result.
Reduced Interdependencies
Well-defined boundaries work both ways: each team operates autonomously without concern for how others complete their tasks. This reduces conflicts between teams and accelerates development through standardized interactions. Additionally, a high level of independence is maintained—each team can develop its implementation without needing to track other teams' work, as long as they adhere to the contract.
Scalability and Compatibility
With Contract First, systems can be adapted to changes without disrupting the overall infrastructure. Since all infrastructure specifics are documented in the contract, scaling becomes easier. When new API methods or services need to be added, the existing contract can be expanded or a new one created to define how the new service interacts with others.
Cost Reduction
By enabling parallel task execution, this approach speeds up development, increases efficiency, and ultimately lowers costs.
Limitations of the Approach
The main challenge of Contract First is the need for strong negotiation skills. Agreements must be highly precise, which is not a skill everyone possesses. The contract formalizes these agreements, and the frequency of renegotiation depends on how accurately the contract is initially defined. While this is not an inherent limitation of the approach, it does require teams to cultivate this skill.
Proper implementation can help mitigate these challenges. The process should start small—for example, one person drafts expectations, then other specialists contribute. Contract First should be introduced from the top down, with leadership setting the example. For long-term success, this approach must become part of the company's culture. Employees should be encouraged to adhere to these standards, and those who resist may need to be retrained—or in extreme cases, replaced.
Other limitations stem from the same issue: an inability to establish precise agreements. For instance, "opaque" contracts with unpredictable behavior can significantly complicate development. Another potential mistake is modifying a contract without informing its stakeholders.
Contract First in the Software Development Lifecycle
Contracts should be published before implementation begins. Clearly defining responsibilities—who does what, under which rules, and with what expected outcome—is crucial.
The Contract First approach streamlines and accelerates every stage of development:
- Design
- Development
- Testing
Once a contract is agreed upon, different tasks can be carried out simultaneously. One developer might work on a new API method, another on testing, while another explores use-case scenarios.
By establishing interfaces between different modules in advance, multiple developers can work on the same task. For example, three developers can work on a single method:
- One writes the API layer,
- Another handles the use case logic,
- The third develops the adapter code.
As a result, instead of taking several days, the task might be completed in just a few hours. If the contract is followed, the system will function as expected.
Applying Contract First in Microservice Architecture
Contract First is particularly well-suited for microservice architecture, which involves developing loosely coupled, independent modules. Under this methodology, a single application/service can consist of multiple microservices, such as API gateways, project services, archives, notifications, and more.
Contract First and microservice architecture share common principles:
- Clear division of service responsibilities
- Independent development of services
When using Contract First, each module can be developed by a separate team, as fundamental rules and standards have been pre-established. This contract-based separation ensures well-defined responsibilities.
Applying Contract First in microservices allows for easy scaling and system resilience, even if some modules become unavailable. The independence of microservices is achieved through strict functional isolation, well-defined contracts, and standardized interaction methods.
Extending the Approach to Processes and Teams
Contract First is not just applicable to API and service architecture—it can also be used to define interactions between teams and departments. The idea is that all parties—whether teams, departments, or companies—agree on specific interaction rules. Each party then works independently, and the contract ensures predictable results.
For smooth collaboration, expectations must be clearly defined: which tasks belong to which team, what each team provides to the other, and so on. It is beneficial to have a project or communication lead responsible for coordinating work and ensuring contract adherence. If all parties follow the agreement, collaboration will be smooth. If the existing terms no longer serve their purpose, they can be updated or terminated.
Practical Implementation and Examples
A key example is API Gateway development, which serves as the central interaction hub for microservices. API Gateways manage request routing between users and microservices, essentially distributing user requests across different services.
For instance, when a user clicks "Buy," the API Gateway's "Buy" method is triggered with a clearly defined input and output structure. Various microservices—such as authentication, payment processing, inventory management, and order processing—then handle the request.
During the development of EyeON, our market monitoring tool, defining the product's initial architecture was our first challenge. After identifying the core services and their primary functions, we proceeded with defining service contracts. We chose gRPC as the API standard for all services and used Protobuf to format messages within our queues. This immediately solved the issue of API documentation and sharing, as Protobuf files inherently define these aspects. Once a Protobuf file was committed and tagged in Git, it became the official service contract, ready for use by other services.
Another challenge was requesting data from different teams at Semrush. Some teams already had APIs we could use, while others did not. We held meetings to explain our needs, and colleagues returned with solutions. Initially, our contracts were simple—"fetch data from here"—but we soon realized this was insufficient. We then created a detailed document outlining our requirements, including SLOs and data delivery mechanisms. This document was reviewed and approved by all stakeholders, making it a formalized contract backed by documented agreements.
Conclusion
Contract First is a highly versatile approach that can be applied to both API and microservice development, as well as structuring team interactions. It turns service development into a modular, standardized process, ensuring predictability while allowing parallel work on different components. Ultimately, this leads to faster development, improved efficiency, and cost reduction.