Planet API Endpoints
Relevant source files
The following files were used as context for generating this wiki page:
The Planet API endpoints provide a set of type-safe RPC-style operations for managing "planet" data within the application. This system follows a contract-first approach, where the API shape, data models, and validation rules are defined in a shared packages/contract package. This contract is then implemented by the apps/api server and can be consumed by any client, ensuring type safety across the entire stack.
The API is built using oRPC, with Zod for schema definition and validation. It exposes standard CRUD-like functionality for planets, including creating, listing, finding, and updating them. Some endpoints are public, while others require authentication. The current implementation uses an in-memory fake database for data persistence.
Sources: README.md, packages/contract/src/contract/planet.ts, apps/api/src/router/planet.ts
API Contract Definition
The core of the Planet API is defined in the @contract-based-monorepo/contract package. This package establishes the routes, methods, and data schemas that both the server and client must adhere to.
Sources: packages/contract/README.md, packages/contract/src/contract/planet.ts
Endpoints
The contract defines four distinct endpoints for interacting with planet resources. These are defined using oc.route from @orpc/contract, which specifies the HTTP method, path, and metadata like summary and tags for OpenAPI generation.
| Method | Path | Summary | Authentication | Source File |
|---|---|---|---|---|
GET | /planets | List all planets | Public | packages/contract/src/contract/planet.ts:7-10 |
POST | /planets | Create a planet | Authenticated | packages/contract/src/contract/planet.ts:19-25 |
GET | /planets/{id} | Find a planet | Public | packages/contract/src/contract/planet.ts:27-33 |
PUT | /planets/{id} | Update a planet | Authenticated | packages/contract/src/contract/planet.ts:40-46 |
The planet contract is exported as part of the main application contract.
Sources: packages/contract/src/contract/index.ts:2, 11-16
Data Models and Schemas
Data structures are defined using Zod schemas, providing runtime validation and static type inference. The primary schemas are NewPlanetSchema, UpdatePlanetSchema, and PlanetSchema.
The following diagram illustrates the relationship between the Planet and User schemas.
This diagram shows that a USER can create one or more PLANET entities.
Sources: packages/contract/src/schemas/planet.ts:22-27
NewPlanetSchema
Used for creating a new planet. It does not contain server-generated fields like id or creator.
| Field | Type | Optional | Description |
|---|---|---|---|
name | z.string() | No | The name of the planet. |
description | z.string() | Yes | A description of the planet. |
image | oz.file().type("image/*") | Yes | An optional image file for the planet. |
Sources: packages/contract/src/schemas/planet.ts:11-15
UpdatePlanetSchema
Used for updating an existing planet. It requires the id of the planet to be updated.
| Field | Type | Optional | Description |
|---|---|---|---|
id | z.number().int().min(1) | No | The unique identifier of the planet. |
name | z.string() | No | The new name of the planet. |
description | z.string() | Yes | A new description for the planet. |
image | oz.file().type("image/*") | Yes | A new optional image file for the planet. |
Sources: packages/contract/src/schemas/planet.ts:17-22
PlanetSchema
The canonical representation of a planet object as returned by the API.
| Field | Type | Optional | Description |
|---|---|---|---|
id | z.number().int().min(1) | No | The unique identifier of the planet. |
name | z.string() | No | The name of the planet. |
description | z.string() | Yes | A description of the planet. |
imageUrl | z.string().url() | Yes | The URL of the planet's image. |
creator | UserSchema | No | The user who created the planet. |
Sources: packages/contract/src/schemas/planet.ts:24-30
Server-Side Implementation
The API server in apps/api provides the concrete implementation for the routes defined in the contract. It uses handlers to process requests, interact with a data layer, and return responses.
Sources: apps/api/src/router/planet.ts
Request Handling Flow
The following diagram shows the general flow of a request to a planet endpoint.
This flowchart illustrates how a request is processed through the server, from routing and middleware to the database and back.
Sources: apps/api/src/router/planet.ts, apps/api/src/middlewares/db.ts
Route Handlers
Each endpoint in the contract is implemented by a handler in apps/api/src/router/planet.ts. These handlers are responsible for executing the business logic.
listPlanets: A public (pub) endpoint that retrieves a list of planets from the database. It includes aretrymiddleware that will attempt the operation up to 3 times on failure.createPlanet: An authenticated (authed) endpoint that creates a new planet, associating it with the currently logged-in user.findPlanet: A public (pub) endpoint to find a single planet by its ID. It also uses theretrymiddleware. If the planet is not found, it throws aNOT_FOUNDerror.updatePlanet: An authenticated (authed) endpoint to update an existing planet. It first checks if the planet exists before proceeding with the update.
Sources: apps/api/src/router/planet.ts:4-39
The sequence diagram below details the createPlanet flow.
This diagram shows the interactions between the router, database middleware, and the fake database when creating a new planet.
Sources: apps/api/src/router/planet.ts:8-12, apps/api/src/middlewares/db.ts:77-92
Database Middleware & Fake DB
The API uses a middleware to provide a database context (db) to the route handlers. The dbProviderMiddleware is responsible for creating and injecting a DB instance.
The project currently uses a mock implementation, createFakeDB, which stores data in an in-memory array. This is useful for development and testing but is not a persistent data store.
The DB interface defines the data access methods:
find(id)list(limit, cursor)create(newPlanet, creator)update(updatePlanet)
Sources: apps/api/src/middlewares/db.ts:9-17, 36-121
API Documentation
The contract-first approach allows for automatic generation of OpenAPI documentation. The openAPIGenerator uses the contract object, including the planet definitions, to create a spec.json file. This specification is then served using Scalar for an interactive API reference UI.
Sources: apps/api/src/handlers/openapi.ts:9-29
Conclusion
The Planet API endpoints are a well-structured and type-safe module within the monorepo. By leveraging a contract-first architecture with oRPC and Zod, the system ensures consistency between the server and potential clients. The separation of the contract definition, server implementation, and data layer (even if currently a mock) provides a clean and maintainable structure. The use of middleware for concerns like authentication, retries, and database injection further enhances the modularity of the design.