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.
Database schema migration
In order to run schema migrations you need to expose your database connection string. Create a .env.migration
file to set the database connection URI for migration scripts, or alternatively, export the DB_CONNECTION_URI
environment variable.
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.
- If you’re adding a new table, update the
TableName
enum in/src/db/schemas/models.ts
to include the new table name. - Create a new migration file by running
npm run migration:new
and give it a relevant name, such asfeature-x
. - Navigate to
/src/db/migrations/<timestamp>_<feature-x>.ts
. - Modify both the
up
anddown
functions to create or alter Postgres fields on migration up and to revert these changes on migration down, ensuring idempotency as outlined here.
Generating TS Schemas
While typically you would need to manually write TS types for Knex type-sense, we have automated this process:
- Start the server.
- Run
npm run migration:latest
to apply all database changes. - Execute
npm run generate:schema
to automatically generate types and schemas using zod in the/src/db/schemas
folder. - 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
:
- Execute
npm run generate:component
. - Choose option 1 for the service component.
- Name the service in dash-case, like
feature-x
. This will create afeature-x
folder in/src/services
containing three files.feature-x-dal
: The Database Access Layer functions.feature-x-service
: The service layer where all the business logic is handled.feature-x-type
: The types used byfeature-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:
- Add the service type in the
fastify.d.ts
file under theservice
namespace of a FastifyServerInstance type. - In
/src/server/routes/index.ts
, instantiate the required dependencies forfeature-x
, such as the DAL and service layers, and then pass them tofastify.register("service,{...dependencies})
. - 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
- To create a route component, run
npm run generate:component
. - 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>
- Implement your logic to connect with the service layer as needed.
- Import the router component in the version folder’s index.ts. For instance, if it’s in v1, import it in
v1/index.ts
. - Finally, register it under the appropriate prefix for access.
Was this page helpful?