ts-rest / ts-rest

RPC-like client, contract, and server implementation for a pure REST API
https://ts-rest.com
MIT License
2.11k stars 91 forks source link

One contract per route #596

Closed samu closed 1 month ago

samu commented 1 month ago

I would like to organize my codebase by use case and not by entity. For example, the docs describe the following structure for the entity "Post":

export const contract = c.router({
  createPost: {...},
  getPosts: {...},
});

As you can see, the contract mixes multiple use cases (creating a Post and retrieving a Post).

I would prefer it if i could define two contracts separately:

// api/posts/get/contract.ts
export const contract = c.router({...});
// api/posts/post/contract.ts
export const contract = c.router({...});

Then, i would like to create routes like this:

// api/posts/get/route.ts
import {contract} from "./contract";

registerRoute(contract, async ({ body }) => {
  return {
    status: 201,
    body: {...},
  };
});
// api/posts/post/route.ts
import {contract} from "./contract";

registerRoute(contract, async ({ body }) => {
  return {
    status: 201,
    body: {...},
  };
});
Gabrola commented 1 month ago

You can define a single endpoint contract using c.query or c.mutation, and assuming you are using a Next.js backend, you can define a single endpoint handler using createSingleRouteHandler as documented here