Skip to main content

Overview

The registration endpoint allows new users to create an account in the Library Management system. The registration process creates both an authentication record (AuthUser) and a user profile record (User) in a single atomic transaction.

Registration Endpoint

curl -X POST "https://api.example.com/api/v1/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "birthDate": "1990-05-15",
    "username": "johndoe",
    "password": "SecurePass123!",
    "email": "[email protected]"
  }'

Request Format

Endpoint Details

  • URL: /api/v1/auth/register
  • Method: POST
  • Content-Type: application/json
  • Authentication: Not required (public endpoint)

Request Body Schema

The request body must be a JSON object conforming to the AuthRegisterRequest DTO:
{
  "name": "string",
  "birthDate": "YYYY-MM-DD",
  "username": "string",
  "password": "string",
  "email": "string"
}

Field Requirements

FieldTypeRequiredValidationDescription
nameStringYesNot blankUser’s full name
birthDateString (ISO 8601)YesMust be past or present dateUser’s date of birth in YYYY-MM-DD format
usernameStringYesNot blank, must be uniqueDesired username for the account
passwordStringYesNot blankPassword for the account (will be encrypted)
emailStringYesValid email format, must be uniqueUser’s email address
All fields are mandatory and will be validated according to the constraints defined in the AuthRegisterRequest DTO.

Validation Rules

Field-Level Validation

1

Name Validation

  • Must not be blank (empty or whitespace only)
  • No specific format restrictions
2

Birth Date Validation

  • Must be a valid ISO 8601 date (YYYY-MM-DD)
  • Must be in the past or present (not future)
  • Will be parsed to LocalDate
3

Username Validation

  • Must not be blank
  • Must be unique across all users
  • Case-sensitive
4

Password Validation

  • Must not be blank
  • No minimum length enforced at API level (consider implementing in production)
  • Will be hashed using BCrypt before storage
5

Email Validation

  • Must not be blank
  • Must match standard email format (validated by @Email annotation)
  • Must be unique across all users
The username and email must be unique. If either already exists in the system, the registration will fail with a specific error message.

Response Format

Success Response (201 Created)

{
  "username": "johndoe",
  "email": "[email protected]",
  "message": "User successfully registered",
  "status": true
}

Response Fields

FieldTypeDescription
usernameStringThe username of the newly created account
emailStringThe email address associated with the account
messageStringConfirmation message (“User successfully registered”)
statusBooleanAlways true for successful registration

Registration Process

The registration process follows these steps:
1

Validate Request Data

The API validates all fields against their constraints (required, format, etc.)
2

Check Username Uniqueness

Verifies that the username is not already in use
if (authUserRepository.existsByUsername(username)) {
    throw new UsernameAlreadyExistsException("The username is already in use");
}
3

Check Email Uniqueness

Verifies that the email is not already registered
if (authUserRepository.existsByEmail(email)) {
    throw new EmailAlreadyExistsException("Email is already in use");
}
4

Hash Password

Encrypts the password using BCrypt algorithm
String encodedPassword = passwordEncoder.encode(password);
5

Generate User ID

Creates a unique UUID for the user (shared between AuthUser and User entities)
UUID userId = UUID.randomUUID();
6

Create AuthUser Record

Saves authentication credentials to the auth_user table
AuthUser authUser = AuthUser.builder()
        .id(userId)
        .username(username)
        .password(encodedPassword)
        .email(email)
        .isEnabled(true)
        .accountNoExpired(true)
        .accountNoLocked(true)
        .credentialNoExpired(true)
        .build();
authUserRepository.save(authUser);
7

Create User Profile

Saves user profile information to the user table
User user = User.builder()
        .id(userId)
        .userName(username)
        .name(name)
        .birthDate(birthDate)
        .books(new ArrayList<>())
        .build();
userRepository.save(user);
8

Return Success Response

Returns confirmation with username and email
The registration process is transactional (annotated with @Transactional). If any step fails, all database changes are rolled back to maintain data integrity.

Password Security

BCrypt Hashing

Passwords are never stored in plain text. The API uses BCrypt, a secure one-way hashing algorithm:
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

BCrypt Features

  • One-way hashing: Cannot reverse the hash to get the original password
  • Salt integration: Each password has a unique salt automatically generated
  • Adaptive: Computational cost can be adjusted as hardware improves
  • Slow by design: Makes brute-force attacks computationally expensive
While the API enforces BCrypt hashing, consider implementing password strength requirements (minimum length, complexity rules) in production environments.

Error Responses

Username Already Exists (409 Conflict)

{
  "message": "The username is already in use",
  "timestamp": "2024-03-06T10:30:00",
  "details": []
}

Email Already Exists (409 Conflict)

{
  "message": "Email is already in use",
  "timestamp": "2024-03-06T10:30:00",
  "details": []
}

Validation Errors (400 Bad Request)

{
  "message": "Validation failed",
  "timestamp": "2024-03-06T10:30:00",
  "details": [
    "The username is obligatory",
    "Must be a valid email address",
    "The date of birth must be a past or present date"
  ]
}

Complete Registration Example

Step-by-Step Registration

1

Prepare Registration Data

Collect user information from your application’s registration form
const registrationData = {
  name: document.getElementById('name').value,
  birthDate: document.getElementById('birthDate').value,
  username: document.getElementById('username').value,
  password: document.getElementById('password').value,
  email: document.getElementById('email').value
};
2

Send Registration Request

POST the data to the registration endpoint
const response = await fetch('https://api.example.com/api/v1/auth/register', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(registrationData)
});
3

Handle Response

Process the response based on status code
if (response.status === 201) {
  const data = await response.json();
  console.log('Success:', data.message);
  // Redirect to login page
  window.location.href = '/login';
} else {
  const error = await response.json();
  console.error('Registration failed:', error.message);
  // Display error to user
  showError(error.message);
}
4

Proceed to Login

After successful registration, direct the user to login with their new credentials

Best Practices

For API Consumers

  1. Validate Input Client-Side: Check format and required fields before sending the request
  2. Secure Password Handling: Never log or expose passwords in client code
  3. Handle Errors Gracefully: Provide clear feedback for username/email conflicts
  4. Redirect After Success: Guide users to the login page after successful registration
  5. Use HTTPS: Always communicate over secure connections

For API Developers

  1. Enforce Password Policies: Add minimum length and complexity requirements
  2. Rate Limiting: Implement rate limiting to prevent registration spam
  3. Email Verification: Consider adding email verification before activation
  4. Audit Logging: Log registration attempts for security monitoring
  5. Data Privacy: Ensure compliance with GDPR and other regulations

Database Records Created

AuthUser Table

Stores authentication credentials:
ColumnTypeValue
idUUIDGenerated UUID (shared with User table)
nameStringUser’s full name
birth_dateLocalDateUser’s date of birth
usernameStringUnique username
passwordStringBCrypt hashed password
emailStringUnique email address
create_atLocalDateTimeAuto-generated timestamp
is_enableBooleantrue
account_no_expiredBooleantrue
account_no_lockedBooleantrue
credential_no_expiredBooleantrue

User Table

Stores user profile information:
ColumnTypeValue
idUUIDSame UUID as AuthUser
user_nameStringUsername
nameStringFull name
birth_dateLocalDateDate of birth
booksListEmpty list (initialized)
The same UUID is used for both tables, establishing a one-to-one relationship between authentication credentials and user profile.

Testing Registration

Valid Registration Test

curl -X POST "http://localhost:8080/api/v1/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test User",
    "birthDate": "1995-01-01",
    "username": "testuser",
    "password": "password123",
    "email": "[email protected]"
  }'

Expected Response

{
  "username": "testuser",
  "email": "[email protected]",
  "message": "User successfully registered",
  "status": true
}

Next Steps

After successfully registering, users can:

Login

Authenticate with your new credentials to receive a JWT token

JWT Tokens

Learn how to use JWT tokens for API requests

User Management

Explore user profile management endpoints

Books API

Start managing your book collection

Build docs developers (and LLMs) love