📍 Location
Location provides a hierarchical location tree: public reads and administrator-only creation, updates, and safe deletion through locationService.
Start here
Mount locationService with identities and locations. Bearer is the default; the example uses it. defService, which backs locationService, registers its own JSON parser, so the host-level express.json() below is optional but safe when other mounted routes also need it.
import express from 'express';
import {services} from '@nodeblocks/backend-sdk';
const app = express();
app.use(express.json());
app.use(
'/api',
services.locationService(
{identities, locations},
{
authSecrets: {authEncSecret: 'replace-me', authSignSecret: 'replace-me'},
identity: {
typeIds: {
admin: 'admin-type-id',
guest: 'guest-type-id',
regular: 'regular-type-id',
},
},
},
),
);
| Configuration | Default / source behavior | Effect |
|---|---|---|
dataStores.locations | Required | All Location blocks read or write it. |
dataStores.identities | Required in the typed LocationServiceDataStore; read by protected routes | The administrator validator loads the caller identity. |
authSecrets | Required in LocationServiceConfiguration; read by protected-route token adapters | Access-token adapters decrypt and verify tokens. |
identity.typeIds.admin | Runtime-required for protected routes | checkIdentityType(['admin']) requires the typeIds object, then compares against its admin entry. |
authMode | Omitted or 'bearer' uses the Authorization header | 'cookie' reads accessToken. |
Cookie mode requires host-installed cookie-parser before the service router. User access tokens always undergo fingerprint comparison; the default IP check only rejects a user-agent mismatch when the IP differs.
Common tasks
| Task | Start with | Contract |
|---|---|---|
| Read a location | getLocationRoute | Public getLocationRoute with getLocationSchema |
| List locations | findLocationsRoute | Public findLocationsRoute with findLocationsSchema |
| Create a hierarchy node | createLocationFeature | createLocationFeature, createLocationRoute, createLocationSchema |
| Change or delete a node | updateLocationRoute | updateLocationRoute or deleteLocationRoute |
Bearer HTTP workflow
An administrator can create POST /api/locations with Authorization: Bearer <admin-access-token>, Content-Type: application/json, and the createLocationSchema body. createLocationRoute returns 201 with the created location. A supplied parentId must identify an existing location; failure is 404.
export API_BASE_URL='http://localhost:8080/api'
export ACCESS_TOKEN='replace-with-an-admin-access-token'
curl -X POST "$API_BASE_URL/locations" \
-H "authorization: Bearer $ACCESS_TOKEN" \
-H 'content-type: application/json' \
-d '{"code":"TOK","name":"Tokyo","type":"city"}'
Cookie HTTP workflow
Set authMode: 'cookie', register cookie-parser before the service router, and send POST /api/locations with the same createLocationSchema body and an accessToken cookie. createLocationRoute remains administrator-only and returns the created location with 201; a missing cookie is rejected with 401 by the selected authentication adapter.
export API_BASE_URL='http://localhost:8080/api'
export ACCESS_COOKIE='accessToken=replace-with-an-admin-access-token'
curl -X POST "$API_BASE_URL/locations" \
-H "cookie: $ACCESS_COOKIE" \
-H 'content-type: application/json' \
-d '{"code":"TOK","name":"Tokyo","type":"city"}'
Custom feature composition
This Bearer-mode fragment requires the same identities, locations, and safe placeholder configuration from the service mount above; dataStores is { identities, locations }. It composes the same five public feature composers in source order. Its POST /api/locations endpoint is createLocationRoute, validates createLocationSchema, returns 201 for an administrator, and returns 401 or 403 when the caller is not authenticated or not an administrator.
import {partial} from 'ramda';
import {features, primitives, utils} from '@nodeblocks/backend-sdk';
const router = primitives.defService(
partial(
primitives.compose(
features.createLocationFeature,
features.getLocationFeature,
features.updateLocationFeature,
features.deleteLocationFeature,
features.findLocationsFeature,
),
[{authenticate: utils.getBearerTokenInfo, configuration, dataStores}],
),
);
app.use('/api', router);
Reference map
| Page | Purpose |
|---|---|
| Blocks | Location persistence, hierarchy, and deletion operations. |
| Features | Schema-to-route composers mounted by the service. |
| Routes | Endpoint, access, and response contracts. |
| Schemas | Request validation contracts. |
| Validators | Shared authentication and administrator checks. |
Related modules
Location service defines service setup. Common validators define administrator access. Auth utilities and cookie utilities define transport behavior.