DEV Community

Jack
Jack

Posted on

Sharing contracts

This is a concept that really drives home how nice it is when your entire stack is written in the same language. I am using node/typescript on the backend which means I can share stuff between the ui and api.

I have a separate repo that holds common stuff like error codes, request payloads and response payloads:

// Contracts export interface SearchProductsRequest { page: number; q: string; } export interface SearchProductsResponse { nextPage: number; products: Product[]; } 
Enter fullscreen mode Exit fullscreen mode

Then I can use that to bridge the gap between api and ui:

// API async function searchProductsApi( req: Request<void, void, void, SearchProductsRequest>, res: Response<SearchProductsResponse> ) { // req.query is strongly typed const result = await search(req.query); // res.send will throw a ts error if result doesn't match the response res.status(200).send(result); } 
Enter fullscreen mode Exit fullscreen mode
// UI // (driver is a simple wrapper around the fetch api) async function searchProducts(args) { // data will be strongly typed const { data } = await driver<SearchProductsRequest, SearchProductsResponse>({ url: "/products", // will throw a ts error is args doesn't match the request data: args, }); } 
Enter fullscreen mode Exit fullscreen mode

Now both sides of my application can have confidence that they will be receiving/sending the same payloads!

Top comments (0)