mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-09 15:38:03 -05:00
55 lines
3.6 KiB
Plaintext
55 lines
3.6 KiB
Plaintext
---
|
|
title: "Backend development guide"
|
|
---
|
|
|
|
Suppose you're interested in implementing a new feature in Infisical's backend, let's call it "feature-x." Here are the general steps you should follow.
|
|
|
|
## Creating new database model
|
|
If your feature involves a change in the database, you need to first address this by generating the necessary database schemas.
|
|
|
|
1. If you're adding a new table, update the `TableName` enum in `/src/db/schemas/models.ts` to include the new table name.
|
|
2. Create a new migration file by going to the `/backend` folder and running `npm run migration:new` and give it a relevant name, such as `feature-x`.
|
|
3. Navigate to `/src/db/migrations/<timestamp>_<feature-x>.ts`.
|
|
4. Modify both the `up` and `down` functions to create or alter Postgres fields on migration up and to revert these changes on migration down, ensuring idempotency as outlined [here](https://github.com/graphile/migrate/blob/main/docs/idempotent-examples.md).
|
|
|
|
### Generating TS Schemas
|
|
|
|
While typically you would need to manually write TS types for Knex type-sense, we have automated this process:
|
|
|
|
1. If you haven't done it yet, create a new `.env.migration` file at the root of the Infisical directory then copy the contents of the file linked [here](https://github.com/Infisical/infisical/blob/main/.env.migration.example)
|
|
2. Start the server.
|
|
3. Go to the `/backend` folder and run `npm run migration:latest-dev` to apply all database changes.
|
|
4. Execute `npm run generate:schema` to automatically generate types and schemas using [zod](https://github.com/colinhacks/zod) in the `/src/db/schemas` folder.
|
|
5. Update the barrel export in `schema/index` and include the new tables in `/src/@types/knex.d.ts` to enable type-sensing in Knex.js.
|
|
|
|
## Business Logic
|
|
|
|
Once the database changes are in place, it's time to create the APIs for `feature-x`:
|
|
|
|
1. Execute `npm run generate:component`.
|
|
2. Choose option 1 for the service component.
|
|
3. Name the service in dash-case, like `feature-x`. This will create a `feature-x` folder in `/src/services` containing three files.
|
|
1. `feature-x-dal`: The Database Access Layer functions.
|
|
2. `feature-x-service`: The service layer where all the business logic is handled.
|
|
3. `feature-x-type`: The types used by `feature-x`.
|
|
|
|
For reusable shared functions, set up a file named `feature-x-fns`.
|
|
|
|
Use the custom Infisical function `ormify` in `src/lib/knex` for simple database operations within the DAL.
|
|
|
|
## Connecting the Service Layer to the Server Layer
|
|
|
|
Server-related logic is handled in `/src/server`. To connect the service layer to the server layer, we use Fastify plugins for dependency injection:
|
|
|
|
1. Add the service type in the `fastify.d.ts` file under the `service` namespace of a FastifyServerInstance type.
|
|
2. In `/src/server/routes/index.ts`, instantiate the required dependencies for `feature-x`, such as the DAL and service layers, and then pass them to `fastify.register("service,{...dependencies})`.
|
|
3. This makes the service layer accessible within all routes under the Fastify service instance, accessed via `server.services.<registered service name>.<function>`.
|
|
|
|
## Writing API Routes
|
|
|
|
1. To create a route component, run `npm run generate:component`.
|
|
2. Select option 3, type the router name in dash-case, and provide the version number. This will generate a router file in `src/server/routes/v<version-number>/<router component name>`
|
|
1. Implement your logic to connect with the service layer as needed.
|
|
2. Import the router component in the version folder's index.ts. For instance, if it's in v1, import it in `v1/index.ts`.
|
|
3. Finally, register it under the appropriate prefix for access.
|