メインコンテンツまでスキップ
バージョン: 🚧 Canary

🛣️ User Routes

User routes provide pre-configured HTTP endpoints for user management operations in Nodeblocks applications. These routes combine handlers, validators, and middleware to create complete API endpoints with proper authentication, authorization, and error handling.


🎯 Overview

User routes are designed to:

  • Provide complete API endpoints for user management operations
  • Combine handlers with validators for secure operations
  • Include authentication and authorization checks
  • Support functional composition patterns
  • Handle logging and error management automatically

📋 Route Structure

Each user route follows a consistent pattern:

  • HTTP Method: Defines the operation type (GET, POST, PATCH, DELETE)
  • Path: Specifies the endpoint URL with parameters
  • Handler: Composed function chain for business logic
  • Validators: Authentication and authorization checks

🔧 Available User Routes

createUserRoute

Creates a new user and returns the created resource.

Purpose: Handles user registration

Route Details:

  • Method: POST
  • Path: /users
  • Authentication: Required (Bearer token)

Handlers: createUser, getUserById, normalizeAvatarOfOwner, normalizeUser, orThrow

Validators: isAuthenticated, some(checkIdentityType(['admin']), isSelf(['params', 'requestBody', 'identityId']))

Usage:

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

// Register route with Express app
app.use('/api', routes.createUserRoute);

getUserRoute

Retrieves a specific user by ID.

Purpose: Fetches user profile data with access control

Route Details:

  • Method: GET
  • Path: /users/:profileId
  • Authentication: Required (Bearer token)

Handlers: getUserById, normalizeAvatarOfOwner, normalizeUser, orThrow

Validators: isAuthenticated, some(checkIdentityType(['admin']), ownsProfile(['params', 'requestParams', 'profileId']))

Usage:

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

// Register route with Express app
app.use('/api', routes.getUserRoute);

findUsersRoute

Retrieves all users with normalized list format.

Purpose: Lists users with pagination and admin-only access

Route Details:

  • Method: GET
  • Path: /users
  • Authentication: Required (Bearer token)

Handlers: findUsers, normalizeAvatarsOfOwners, normalizeUsers, orThrow

Validators: isAuthenticated, checkIdentityType(['admin'])

Usage:

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

// Register route with Express app
app.use('/api', routes.findUsersRoute);

updateUserRoute

Updates an existing user and returns the updated resource.

Purpose: Modifies user data with access control

Route Details:

  • Method: PATCH
  • Path: /users/:profileId
  • Authentication: Required (Bearer token)

Handlers: getUserById, updateUser, getUserById, deleteAvatarIfReplaced, normalizeAvatarOfOwner, normalizeUser, orThrow

Validators: isAuthenticated, some(checkIdentityType(['admin']), ownsProfile(['params', 'requestParams', 'profileId']))

Response (200 OK): Updated user object with normalized avatar URL

Error Responses:

  • 401 Unauthorized: Authentication failed
  • 403 Forbidden: Non-admin user attempting update without ownership
  • 404 Not Found: User not found
  • 500 Internal Server Error: Database operation, avatar cleanup, or avatar normalization failed

Handler Process:

  1. Validates authentication and path parameters
  2. Retrieves user data before update
  3. Updates user data in database
  4. Deletes old avatar file from storage if avatar was replaced
  5. Generates signed URL for new avatar (if exists)
  6. Returns normalized user data with avatar URL

Usage:

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

// Register route with Express app
app.use('/api', routes.updateUserRoute);

deleteUserRoute

Deletes a user by ID with automatic avatar cleanup.

Purpose: Removes user account with access control and cleans up associated avatar files from storage

Route Details:

  • Method: DELETE
  • Path: /users/:profileId
  • Authentication: Required (Bearer token)

Blocks: getUserById, deleteUser, deleteAvatar Terminators: deleteUserTerminator

Validators: isAuthenticated, some(checkIdentityType(['admin']), ownsProfile(['params', 'requestParams', 'profileId']))

Response (204 No Content): Empty response body on successful deletion

Error Responses:

  • 401 Unauthorized: Authentication failed
  • 403 Forbidden: Non-admin user attempting deletion
  • 404 Not Found: User not found
  • 500 Internal Server Error: Database operation or avatar cleanup failed

Handler Process:

  1. Validates authentication and path parameters
  2. Retrieves user data to access avatar information
  3. Deletes user from database
  4. Deletes associated avatar file from storage (if exists)
  5. Returns 204 No Content on successful deletion

Authorization Notes:

  • Currently restricted to admin users or profile owners
  • TODO: Add organization-based access control

Usage:

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

// Register route with Express app
app.use('/api', routes.deleteUserRoute);

// Client usage:
const response = await fetch('/api/users/user-123', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});

if (response.status === 204) {
// User and avatar deleted successfully
}

getAvatarUploadUrlRoute

Returns a signed URL for uploading avatar images via GET /user-profiles/:profileId/avatar-upload-url.

Purpose: Generates pre-signed URLs for secure avatar file uploads with automatic UUID filename generation

Route Details:

  • Method: GET
  • Path: /user-profiles/:profileId/avatar-upload-url
  • Authentication: Required (Bearer token)

Blocks: generateSignedAvatarUploadUrl, orThrow

Validators: isAuthenticated, some(checkIdentityType(['admin']), ownsProfile(['params', 'requestParams', 'profileId']))

Usage:

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

// Use in feature composition:
export const getAvatarUploadUrlFeature = compose(getAvatarUploadUrlSchema, getAvatarUploadUrlRoute);

findProfilesByIdentityIdRoute

Retrieves paginated profiles by identity ID via GET /profiles/identities/:identityId with avatar normalization and self-access control.

Route Configuration:

  • Method: GET
  • Path: /profiles/identities/:identityId
  • Handler: buildIdentityIdFilter, buildWithoutMongoIdFindOptions, findProfiles, normalizeAvatarsOfOwners, applySpec, orThrow
  • Validators: isAuthenticated, isSelf(['params', 'requestParams', 'identityId'])

Handler Process:

  • Input: Identity ID path parameter, authentication token
  • Process: Validates self-access, builds filter, queries profiles, normalizes avatars, applies pagination metadata
  • Output: Paginated profile data with avatar URLs and pagination metadata
  • Errors: ProfileDbBlockError (500), AvatarBlockError (500), authentication errors (401), access denied (403)

Example Usage:

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

// Use in feature composition:
export const findProfilesByIdentityIdFeature = compose(findProfilesByIdentityIdSchema, findProfilesByIdentityIdRoute);

// Register route with Express app
app.use('/api', routes.findProfilesByIdentityIdRoute);

Request:

GET /api/profiles/identities/identity-123?page=1&limit=10
Authorization: Bearer <access-token>

Response (200):

{
"data": [
{
"id": "profile-456",
"name": "John Doe",
"avatar": {
"url": "https://cdn.example.com/avatars/profile-456.jpg",
"type": "image/jpeg"
},
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
],
"metadata": {
"pagination": {
"hasNext": false,
"hasPrev": false,
"limit": 10,
"page": 1,
"total": 1,
"totalPages": 1
}
}
}

Error Responses:

  • 401 Unauthorized: Missing or invalid authentication token
  • 403 Forbidden: Attempting to access profiles of another identity
  • 500 Internal Server Error: Database or avatar processing errors