- Ahmet Acer
Over the past few months, we’ve made a transformational shift in how our applications communicate with APIs. By embracing Contract Driven Development (CDD) and automating API client library generation, we’ve significantly improved efficiency, reduced errors, and enhanced the developer experience. What started as a change within our team is now being adopted across the entire bank organization, enabling all teams to benefit from a streamlined and consistent approachto API integration.
The Backstory: Why Change Was Needed
Previously, our development teams were spending countless hours manually creating and maintaining API clients. This led to:
- Inconsistencies between API and frontend layers due to manual contract updates.
- Duplicated efforts across teams, each implementing API clients in their own way.
- Increased risk of runtime errors, as there was no enforced type safety.
- Slower development cycles, with teams frequently troubleshooting integration issues caused by mismatched contract definitions.
Realized that a more scalable and reliable solution was needed one that could support not just our team but all development teams across the bank.
The Solution: Contract-Driven API Clients
By shifting to Contract-Driven Development (CDD), I have automated the process of generating and deploying API client libraries. Now, every time an API changes, an updated client library is automatically generated, ensuring that all consuming applications remain in sync.
This transformation has been a several months of journey of improving communication between layers. Throughout this time, I contributed to multiple repositories, advocating for this change and aligning teams across the bank. After continuous efforts, have finally arrived at a solution that benefits everyone.
What This Means for Developers
No More Coding and Maintaining
Instead of manually defining API clients, creating functions that constructs API paths, arguments and necessary headers that is needed now developers can easyly install pre generated, type safe API libraries with a simple command:
pnpm add @dnb-api-clients/example1-bank-api
Fully Typed API Clients
The generated libraries provide TypeScript type declarations, ensuring that developers always use the correct request and response formats. Example:
import { AccountsApi } from "@dnb-api-clients/example-bank-api";
const accountsApi = new AccountsApi();
const accounts = await accountsApi.getV1Accounts();
console.log(accounts); // Get your accounts simply as this with 3 lines of code!
Want another example?
await accountsApi.deleteV1AccountsAccountNumber("12345");
await customerApiClient.getV1CustomerFlags();
Strongly Typed Data with Exported Types and Enums
One of the biggest advantages of our generated API clients is the automatic export of TypeScript types and enums. These ensure that API responses and requests conform to a well-defined structure, eliminating ambiguity and runtime errors. Examples include:
import {
AccountsData, // Interface
BankAccountType, // Enum
SavingsAgreementFrequency, // Enum SavingsAgreementsPostData,
SavingsAgreementsPostResponse,
} from "@dnb-api-clients/example-bank-api";
const accountsData: AccountsData = {
bankAccounts: [
{
accountNumber: "12345678901",
accountType: BankAccountType.Ask, // Enforced type safety
},
],
};
export const savingsAgreementsPostData: SavingsAgreementsPostData = {
mergeId: "12345678901",
frequency: SavingsAgreementFrequency.Monthly, // Enforced type safety
};
By leveraging these generated types, developers can build more reliable and maintainable applications while benefiting from intelligent autocomplete and type checking in their IDEs.
Automated Versioning and Notifications
With each API deployment, a new client library version is generated and published. Teams are notified instantly in notification channels, ensuring they always have access to the latest updates.
The Impact: A Bank Wide Transformation
This initiative has already resulted in the removal of 10,000+ lines of duplicated code, significantly reducing manual maintenance efforts. As adoption continues to grow across teams, this number keeps increasing, further streamlining our development process and improving overall efficiency.
What started as an experiment has now become a bank wide best practice. Other teams have quickly realized the benefits of this approach, including:
Consistency across all applications—every frontend now speaks the same language as the backend.
Increased development speed—no more waiting for API documentation updates or manual interface adjustments.
Better collaboration between teams—backend and frontend teams work from a shared API contract, reducing miscommunication and integration issues.
Reduction in API-related bugs—TypeScript type enforcement ensures API mismatches are caught during development before even being published to production.
What’s Next?
As more teams within the bank adopt this approach, we’re exploring additional enhancements:
Extending support for automatically mocking API responses from contract definitions.
Providing more customization options for request handling.
Adding support for other platforms such as iOS and Android.
By making API communication more reliable, efficient, and developer-friendly, we’re setting a new standard for how web applications interact with backend services.
This transformation is just the beginning, and we’re excited to see how it continues to evolve. If you’re working on API integrations, I’d love to hear your thoughts, how do you manage API client consistency in your projects? Please reach out.
A huge thank you to everyone who supported this transformation whether through feedback, or simply embracing the change. Your collaboration has been invaluable in making this a success!
Thanks for reading!