Skip to main content
The user registration feature allows new users to create accounts in the Karma Ecommerce system. It follows CQRS principles with clear separation between commands and queries.

Overview

The registration system implements the Command pattern with these layers:
  • UI Layer: Register page component for user interaction
  • Application Layer: Command handlers execute registration logic
  • Domain Layer: Repository contract definition
  • Infrastructure Layer: AuthService handles HTTP communication

Registration Flow

1

User submits registration

The user clicks the register button with username and password.
2

Component calls AuthService

The RegisterPage component invokes registrarUsuario() method.
3

HTTP POST request

AuthService sends a POST request to http://localhost:8080/registro with user credentials in the request body.
4

Response handling

RxJS operators process success/error responses and display appropriate alerts.

Component Implementation

The register page component is located at ~/workspace/source/src/app/usuario/infrastructure/ui/pages/register-page/register-page.ts:1:
import { Component } from '@angular/core';
import { AuthService } from '../../../services/auth-service';
import { catchError, tap, throwError } from 'rxjs';

@Component({
  selector: 'app-register-page',
  imports: [],
  templateUrl: './register-page.html',
  styleUrl: './register-page.css',
})
export class RegisterPage {

  constructor(private authService: AuthService) { }

  registrar(usuario: string, contrasena: string) {
    this.authService.registrarUsuario(usuario, contrasena).pipe(
      tap(usuario => {
        console.log('usuario', usuario);
        usuario ? 
          alert('usuario registrado correctamente') : 
          alert(usuario);
      }), 
      catchError(err => {
        const mensaje = err.error ? err.error : 'Error desconocido';
        alert(`Error al registrar: ${mensaje}`);
        return throwError(() => err);
      })
    ).subscribe();
  }
}

Template

The registration template at ~/workspace/source/src/app/usuario/infrastructure/ui/pages/register-page/register-page.html:1:
<button (click)="registrar('ivan', 'patatas123')">REGISTRO</button>
Development Note: The template currently hardcodes credentials for testing. Production implementations should use Angular Reactive Forms or Template-driven Forms with proper validation.

CQRS Pattern: Command & Handler

Register Command

The RegisterUserCommand encapsulates registration data at ~/workspace/source/src/app/usuario/application/commands/register-user.command.ts:1:
export class RegisterUserCommand {
    constructor( readonly usuario: string, readonly contrasena: string){}
}

Register Handler

The RegisterUserHandler processes registration commands at ~/workspace/source/src/app/usuario/application/usecases/commandHandlers/register-user.handler.ts:1:
import { Injectable } from "@angular/core";
import { UsuarioRepository } from "../../../domain/repositories/usuario.repository";
import { RegisterUserCommand } from "../../commands/register-user.command";
import { Observable } from "rxjs";
import { Usuario } from "../../../domain/models/usuario";

@Injectable()
export class RegisterUserHandler {
    constructor(private usuarioRepository: UsuarioRepository) {}

    handle(command: RegisterUserCommand): Observable<Usuario> {
        return this.usuarioRepository.registrarUsuario(command.usuario, command.contrasena);
    }
}

API Integration

Registration Endpoint

URL: http://localhost:8080/registro
Method: POST
Content-Type: application/json
Request Body:
{
  "usuario": "string",
  "contrasena": "string"
}
Response: Usuario object
interface Usuario {
    id: number,
    usuario: string,
    contrasena: string
}

Request Example

curl -X POST http://localhost:8080/registro \
  -H "Content-Type: application/json" \
  -d '{
    "usuario": "ivan",
    "contrasena": "patatas123"
  }'

AuthService Implementation

The registrarUsuario() method in AuthService at ~/workspace/source/src/app/usuario/infrastructure/services/auth-service.ts:18:
registrarUsuario(usuario: string, contrasena: string): Observable<Usuario> {
  const body = { usuario, contrasena };
  return this.httpClient.post<Usuario>(
    `${this.BASE_URL}registro`,
    body,
    { headers: { 'Content-Type': 'application/json' } }
  );
}
Key implementation details:
  • Creates request body with username and password
  • Uses HTTP POST method (unlike login which uses GET)
  • Sets Content-Type header to application/json
  • Returns Observable<Usuario> for reactive handling

Error Handling

The registration component implements comprehensive error handling using RxJS operators:
this.authService.registrarUsuario(usuario, contrasena).pipe(
  tap(usuario => {
    console.log('usuario', usuario);
    usuario ? 
      alert('usuario registrado correctamente') : 
      alert(usuario);
  }), 
  catchError(err => {
    const mensaje = err.error ? err.error : 'Error desconocido';
    alert(`Error al registrar: ${mensaje}`);
    return throwError(() => err);
  })
).subscribe();

Error Handling Features

  • tap operator: Handles successful registration with user feedback
  • catchError operator: Intercepts HTTP errors and displays user-friendly messages
  • throwError: Re-throws error for potential upstream handling
  • Error message extraction: Attempts to extract server error message from response
Error Handling: The current implementation extracts error messages from err.error. Ensure your backend API returns error details in this format for proper error display.

Form Handling & Validation

While the current implementation demonstrates the core flow, production applications should implement:
  1. Reactive Forms: Use Angular Reactive Forms for better control
  2. Field Validation:
    • Username length and format validation
    • Password strength requirements
    • Confirmation password matching
  3. Client-side Validation: Validate before sending API request
  4. Loading States: Show spinner during registration
  5. Form Disable: Prevent multiple submissions

Example Production Form

import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';

export class RegisterPage {
  registerForm = this.fb.group({
    usuario: ['', [Validators.required, Validators.minLength(3)]],
    contrasena: ['', [Validators.required, Validators.minLength(8)]],
    confirmarContrasena: ['', [Validators.required]]
  });

  constructor(
    private authService: AuthService,
    private fb: FormBuilder
  ) {}

  onSubmit() {
    if (this.registerForm.valid) {
      const { usuario, contrasena } = this.registerForm.value;
      this.registrar(usuario, contrasena);
    }
  }
}

Success Handling

Upon successful registration:
  1. Console Logging: User object logged for debugging
  2. User Notification: Alert displays success message
  3. Next Steps: Consider redirecting to login page or dashboard
tap(usuario => {
  console.log('usuario', usuario);
  if (usuario) {
    // Store user session/token
    // Navigate to dashboard or login
    this.router.navigate(['/login']);
  }
})

Security Considerations

Critical Security Notes:
  • Passwords are transmitted in plain text - implement HTTPS in production
  • Server should hash passwords before storage (bcrypt, Argon2)
  • Consider implementing CSRF protection
  • Add rate limiting to prevent abuse
  • Implement CAPTCHA for bot prevention
  • Use JWT or session tokens for authentication state

Repository Pattern

The registration uses the same UsuarioRepository abstract class as authentication:
export abstract class UsuarioRepository {
    abstract loginUsuario(usuario: string, contrasena: string): Observable<Usuario>;
    abstract registrarUsuario(usuario: string, contrasena: string): Observable<Usuario>;
}
This abstraction allows:
  • Dependency injection flexibility
  • Easy testing with mock implementations
  • Swapping implementations without changing business logic

User Journey

1

Navigate to registration page

User accesses the registration page in the application.
2

Enter credentials

User provides username and password (via form inputs in production).
3

Submit registration

User clicks the registration button.
4

API processing

Backend validates credentials and creates user account.
5

Receive confirmation

User sees success message and can proceed to login.

Build docs developers (and LLMs) love