Skip to main content
Version: 0.14.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.