Skip to main content
Version: 0.15.0 (Latest)

📂 Category

Category exposes public category reads and administrator-only creation, editing, status, and deletion operations through categoryService.

Start here​

Mount the service below /api. It needs MongoDB categories and identities collections, authSecrets, and configured identity type IDs for protected mutations. defService installs JSON parsing on the returned router; register cookie-parser before the service only when authMode is 'cookie'.

The exported categoryService is a Service<CategoryServiceDataStore, CategoryServiceConfiguration> that returns an Express router from (dataStores, configuration, drivers?).

import express from 'express';
import { services } from '@nodeblocks/backend-sdk';

const app = express();
app.use('/api', services.categoryService(
{ categories, identities },
{
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET!,
authSignSecret: process.env.AUTH_SIGN_SECRET!,
},
authMode: 'bearer',
identity: { typeIds: { admin: 'admin-type-id', guest: 'guest-type-id', regular: 'regular-type-id' } },
},
));
ConfigurationDefault / source behaviorEffect
authSecrets.authEncSecret / authSecrets.authSignSecretRequired by the service configuration; passed to authentication utilitiesRequired runtime authentication configuration.
identity.typeIds.adminRequired by protected-route authorization; read by checkIdentityType(['admin'])Selects the identity type allowed to mutate categories.
authModeOmitted or 'bearer' selects getBearerTokenInfo; 'cookie' selects getCookieTokenInfoChanges the protected-route token transport.

Public routes do not compose authentication validators. Protected routes run isAuthenticated() and then checkIdentityType(['admin']); cookie mode therefore requires cookie middleware in the host application.

The service executor returns ordinary handler values through res.json(result), which supplies the 200 status documented for Category read/create/update routes. A terminator that returns { statusCode: 204 } instead uses res.status(204).json(undefined). Category defines no domain block exports; its routes use Category handlers plus shared entity and pagination utilities.

Common tasks​

TaskStart withContract
Read one category or list categoriesPublic routesRoutes and list schema
Create or edit a categoryAdministrator access token or cookieCreate, update
Change status or deleteAdministrator access token or cookieStatus and delete routes
Compose selected endpointsFeature composersFeatures

Bearer HTTP workflow​

Declare the shell values before using a protected endpoint:

export ADMIN_ACCESS_TOKEN='replace-with-an-admin-access-token'
export CATEGORY_ID='replace-with-a-category-id'

curl 'http://localhost:8080/api/categories?name=Electronics&page=1&limit=20'

curl -X POST 'http://localhost:8080/api/categories' \
-H "authorization: Bearer $ADMIN_ACCESS_TOKEN" \
-H 'content-type: application/json' \
-d '{"name":"Electronics","description":"Devices and accessories","status":"active"}'

curl -X POST "http://localhost:8080/api/categories/$CATEGORY_ID/disable" \
-H "authorization: Bearer $ADMIN_ACCESS_TOKEN"

The list returns 200 with { data, metadata: { pagination } }; omitted pagination values default to page 1 and limit 10. Creation returns 200 with the normalized category. Disabling succeeds with an empty 204; a missing category is rejected by doesCategoryExist with 404. See the route matrix and request schemas.

With authMode: 'cookie', register cookie-parser before the Category mount, obtain the access cookie through the Authentication cookie workflow, then send the stored cookie rather than an Authorization header:

export CATEGORY_ID='replace-with-a-category-id'

curl -X PATCH "http://localhost:8080/api/categories/$CATEGORY_ID" \
-b cookies.txt \
-H 'content-type: application/json' \
-d '{"description":"Updated category description"}'

This request requires the same administrator identity as the Bearer workflow and returns the normalized category on success.

Custom feature composition​

This fragment mounts only create, list, and status operations. Its host must provide categories, identities, authentication secrets, and identity type IDs. defService installs JSON parsing; cookie mode additionally needs cookie-parser.

import { partial } from 'ramda';
import { features, primitives, utils } from '@nodeblocks/backend-sdk';

const composeCategoryRoutes = primitives.compose(
features.createCategoryFeature,
features.findCategoriesFeatures,
features.editCategoryStatusFeatures,
);

const configuration = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET!,
authSignSecret: process.env.AUTH_SIGN_SECRET!,
},
identity: {
typeIds: {
admin: 'admin-type-id',
guest: 'guest-type-id',
regular: 'regular-type-id',
},
},
};

const categoryRouter = primitives.defService(partial(composeCategoryRoutes, [{
authenticate: utils.getBearerTokenInfo,
configuration,
dataStores: { categories, identities },
}]));

app.use('/api', categoryRouter);

For cookie transport, substitute utils.getCookieTokenInfo and register cookie-parser in the host application.

Reference map​

PagePurpose
FeaturesSchema and route composition.
HandlersPipeline operations and response terminators.
RoutesExact endpoint, access, and response contracts.
SchemasRequest and reusable object contracts.
ValidatorsCategory-existence and shared access guards.

There is no Category blocks page because the SDK exports no Category-specific block layer.

See Category service for service-level use, Authentication for access-token and cookie setup, validator component for route validation, and error handling for shared error responses.