The BaseController
Class
The BaseController
class provides standardized RESTful API endpoints for any given prisma model in your application. It follows a standard controller pattern that handles common CRUD operations through a consistent interface, reducing code duplication across the application.
By default it is an Arkos internal utility class for handling the auto generated api endpoints, but this is exposed through arkos
so that you can customize the end handler of your CRUD operations.
As stated on the note above this is a class used internally by Arkos and also exposed for you if you want to override and customize the end handler. Hence the next texts is about how Arkos uses it behind the scenes to handle the auto generated endpoints.
Purpose
This class provides a reusable set of controller methods that can be used for any model in the system, implementing standard REST operations.
Constructor
constructor(modelName: string)
- Parameters:
modelName
: The name of the model for which this controller will handle operations.
- Behavior:
- Initializes a new
BaseService
instance for the specified model, read more here. - Loads any model-specific interceptor middlewares from the model modules, see more here.
- Initializes a new
Methods
createOne
Creates a single resource instance.
- HTTP Method:
POST
- Response:
- Status Code:
201 Created
- Body:
{ data: <created resource> }
- Status Code:
- Interceptor Middleware Support:
- Can use
beforeCreateOne
middleware for pre-processing. - Can use
afterCreateOne
middleware for post-processing.
- Can use
createMany
Creates multiple resource instances in a single operation.
- HTTP Method:
POST
- Response:
- Status Code:
201 Created
- Body:
{ total: <total count>, results: <count of created resources>, data: <array of created resources> }
- Status Code:
- Interceptor Middleware Support:
- Can use
beforeCreateMany
middleware for pre-processing. - Can use
afterCreateMany
middleware for post-processing.
- Can use
findMany
Retrieves multiple resources with filtering, sorting, pagination, and field selection.
- HTTP Method:
GET
- Query Parameters:
- Supports filtering, sorting, field limiting, and pagination via
APIFeatures
.
- Supports filtering, sorting, field limiting, and pagination via
- Response:
- Status Code:
200 OK
- Body:
{ total: <total count>, results: <count of returned resources>, data: <array of resources> }
- Status Code:
- Interceptor Middleware Support:
- Can use
beforeFindMany
middleware for pre-processing. - Can use
afterFindMany
middleware for post-processing.
- Can use
findOne
Retrieves a single resource by its identifier.
- HTTP Method:
GET
- URL Parameters:
id
: The ID of the resource to retrieve.
- Query Parameters:
prismaQueryOptions
: Optional Prisma query options as a string.
- Response:
- Status Code:
200 OK
- Body:
{ data: <retrieved resource> }
- Status Code:
- Interceptor Middleware Support:
- Can use
beforeFindOne
middleware for pre-processing. - Can use
afterFindOne
middleware for post-processing.
- Can use
updateOne
Updates a single resource by its identifier.
- HTTP Method:
PUT
orPATCH
- URL Parameters:
id
: The ID of the resource to update.
- Query Parameters:
prismaQueryOptions
: Optional Prisma query options as a string.
- Response:
- Status Code:
200 OK
- Body:
{ data: <updated resource> }
- Status Code:
- Interceptor Middleware Support:
- Can use
beforeUpdateOne
middleware for pre-processing. - Can use
afterUpdateOne
middleware for post-processing.
- Can use
updateMany
Updates multiple resources that match the given criteria.
- HTTP Method:
PUT
orPATCH
- Query Parameters:
- Requires at least one filter criterion.
- Supports filtering and sorting via
APIFeatures
.
- Response:
- Status Code:
200 OK
- Body:
{ total: <total count>, results: <count of updated resources>, data: <array of updated resources> }
- Status Code:
- Interceptor Middleware Support:
- Can use
beforeUpdateMany
middleware for pre-processing. - Can use
afterUpdateMany
middleware for post-processing.
- Can use
- Error Handling: Returns
400 Bad Request
if no filter criteria are provided.
deleteOne
Deletes a single resource by its identifier.
- HTTP Method:
DELETE
- URL Parameters:
id
: The ID of the resource to delete.
- Response:
- Status Code:
204 No Content
- Status Code:
- Interceptor Middleware Support:
- Can use
beforeDeleteOne
middleware for pre-processing. - Can use
afterDeleteOne
middleware for post-processing.
- Can use
deleteMany
Deletes multiple resources that match the given criteria.
- HTTP Method:
DELETE
- Query Parameters:
- Requires at least one filter criterion.
- Supports filtering and sorting via
APIFeatures
.
- Response:
- Status Code:
200 OK
- Body:
{ total: <total count>, results: <count of deleted resources>, data: <array of deleted resources> }
- Status Code:
- Interceptor Middleware Support:
- Can use
beforeDeleteMany
middleware for pre-processing. - Can use
afterDeleteMany
middleware for post-processing.
- Can use
- Error Handling: Returns
400 Bad Request
if no filter criteria are provided.
Default Endpoints When Auto Generated
Format: /api/[pluralized-model-name]
-
For bulk operations (createMany, updateMany, deleteMany), append /many.
-
For single operations, use the base path and optionally /:id for operations requiring a resource ID.
Function: getAvalibleRoutes
Purpose
Returns a list of all registered API routes in the Express application.
Parameters
req
: The Express request object.res
: The Express response object.next
: The Express next function.
Response
- A JSON array containing objects with
method
andpath
properties for each registered route.
Function: getAvailableResources
Purpose
Returns a list of all available resource endpoints based on the application's models.
Response
- Status Code: 200 (OK)
- Body:
{ data: <array of kebab-cased model names plus "file-upload"> }
Overriding Default Handlers
Creating a Controller for a Specific Model
// src/modules/posts/post.controller.ts
import {
ArkosRequest,
ArkosResponse,
ArkosNextFunction,
BaseController,
} from "arkos";
class UserController extends BaseController {
constructor() {
super("user"); // model-name in kebab-case
// Add any user-specific controller methods or override base methods here
// ✅ Will override the default createOne handler method
createOne: catchAsync(
async (
req: ArkosRequest,
res: ArkosResponse,
next: ArkosNextFunction
) => {
// this.baseService is made available on `BaseController`
const data = await this.baseService.createOne(
req.body,
req.query?.prismaQueryOptions as string
);
res.status(201).json({ data });
}
);
}
}
const userController = new UserController();
export default userController;
Be carreful when overriding the defaults controller handlers as shown above, just do it if you know what you are really doing. Because this way you lose some Arkos built-in features such as (depending on the overridden handler): request query paramaters handling
, auto relation fields handling
, standardized responses it all endpoints
, must create your swagger docs for the endpoints
, intercepetor middlewares injections
and others.
When using before
or after
interceptor middlewares defined in the model's module file, they will be automatically loaded and executed after the corresponding operation but before sending the response even for after
interceptor middlewares, there you can call next()
and Arkos will send the responpse or you can send it youself using the res
object.
You can read more about those interceptor middlewares here.