API Proxy Design

1. Overview

The Registration Portal operates as a JHipster gateway application, proxying most API requests to the admin-service backend. This design provides a clean separation between the presentation layer (Angular) and the business logic layer (Spring Boot services).

Key Benefits:

  • Single Entry Point - All API calls go through gateway

  • Security Layer - Token validation at gateway

  • Service Discovery - Gateway routes requests to correct service

  • Load Balancing - Can distribute requests across service instances

  • Circuit Breaking - Fault tolerance for backend failures

2. Proxy Architecture

proxy-architecture

3. Gateway Routes Configuration

3.1. Route Definitions

spring:
  cloud:
    gateway:
      routes:
        - id: admin-service
          uri: http://localhost:8080
          predicates:
            - Path=/api/**,/services/**
          filters:
            - RewritePath=/(?<segment>.*), /$\{segment}
            - name: Retry
              args:
                retries: 3
                statuses: BAD_GATEWAY,GATEWAY_TIMEOUT
                methods: GET,POST,PUT,DELETE
                backoff:
                  firstBackoff: 10ms
                  maxBackoff: 50ms
                  factor: 2
                  basedOnPreviousValue: false
        - id: admin-service-websocket
          uri: ws://localhost:8080
          predicates:
            - Path=/websocket/**

3.2. Route Patterns

Pattern Destination Purpose

/api/**

admin-service

REST API endpoints

/services/**

admin-service

Microservice endpoints

/websocket/**

admin-service (WebSocket)

Real-time communication

/oauth/**

Local gateway

OAuth2 authentication

/management/**

Local gateway

Actuator endpoints

4. Development Configuration

4.1. Static Routes

It is possible to override the Cloud Gateway functionality by providing static routes. This can be useful during development when you want to route to a locally running admin-service instance.

cloud:
  gateway:
    routes:
      - id: admin-service
        uri: http://localhost:12504
        predicates:
          - Path=/services/admin-service/**
        filters:
          - RewritePath=/services/admin-service/(?<segment>.*), /$\{segment}

The routes key contains an array of objects to define each possible route.

The predicates section defines elements of the search request to be matched. In this case the Path is used. The filters section also lists a rewrite instruction to strip the first part of the path, /services/admin-service/. For instance:

/services/admin-service/acme

is replaced by:

/acme

4.2. Troubleshooting

To view the resolution of routes in Cloud Gateway, enable the following loggers:

logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    org.springframework.http.server.reactive: DEBUG
    org.springframework.web.reactive: DEBUG
    org.springframework.cloud.gateway.handler: TRACE

5. Proxied Endpoints

5.1. Person API

Method Frontend Path Proxied To Service

GET

/api/people/{id}

admin-service

PersonService

POST

/api/people

admin-service

PersonService

PUT

/api/people/{id}

admin-service

PersonService

DELETE

/api/people/{id}

admin-service

PersonService

GET

/api/people/linked

admin-service

PersonService

POST

/api/people/match

admin-service

PersonService

5.2. LinkedPerson API

Method Frontend Path Proxied To Service

POST

/api/linked-people/link/{id}/{type}

admin-service

LinkedPersonService

GET

/api/linked-people

admin-service

LinkedPersonService

DELETE

/api/linked-people/{id}

admin-service

LinkedPersonService

5.3. Form/Process API

Method Frontend Path Proxied To Service

GET

/api/forms/membership/{periodId}

admin-service

FormService

POST

/api/forms/next

admin-service

FormService

POST

/api/forms/processes/{id}/reset

admin-service

ProcessService

POST

/api/forms/processes/{id}/resume

admin-service

ProcessService

5.4. Event Registration API

Method Frontend Path Proxied To Service

GET

/api/events/{id}

admin-service

EventService

POST

/api/event-participants/register

admin-service

EventParticipantService

5.5. Membership API

Method Frontend Path Proxied To Service

GET

/api/membership-periods/{id}

admin-service

MembershipPeriodService

GET

/api/membership-types/{typeId}/persons/obfuscate

admin-service

MembershipService

6. Local Gateway Endpoints

6.1. Authentication Endpoints

Method Path Purpose

POST

/api/auth/external-login

Exchange credentials for session

POST

/oauth/token

Obtain access token (OAuth2 flow)

GET

/oauth/authorize

Authorization code flow

POST

/oauth/logout

Logout and invalidate session

6.2. Management Endpoints

Method Path Purpose

GET

/management/health

Health check

GET

/management/info

Application info

GET

/management/metrics

Prometheus metrics

GET

/management/env

Environment properties

7. Service Configuration

7.1. ApplicationConfigService

The Angular application uses ApplicationConfigService to construct proxied endpoint URLs:

@Injectable({ providedIn: 'root' })
export class ApplicationConfigService {
  private endpointPrefix = '';

  setEndpointPrefix(endpointPrefix: string): void {
    this.endpointPrefix = endpointPrefix;
  }

  getEndpointFor(api: string, microservice?: string): string {
    if (microservice) {
      return `${this.endpointPrefix}services/${microservice}/${api}`;
    }
    return `${this.endpointPrefix}${api}`;
  }
}

Usage Examples:

// Proxied to admin-service
this.applicationConfigService.getEndpointFor('api/people', 'admin-service')
// Returns: "services/admin-service/api/people"

// Direct gateway endpoint
this.applicationConfigService.getEndpointFor('api/account')
// Returns: "api/account"

8. Request Flow

8.1. Standard API Request

api-request-flow

9. Error Handling

9.1. Circuit Breaker

The gateway includes circuit breaker patterns for fault tolerance:

Configuration:

resilience4j:
  circuitbreaker:
    instances:
      admin-service:
        failureRateThreshold: 50
        waitDurationInOpenState: 10s
        slidingWindowSize: 10
        minimumNumberOfCalls: 5

Behavior:

  • Closed - Normal operation, requests flow through

  • Open - Too many failures, requests immediately fail with 503

  • Half-Open - Testing if service recovered, limited requests allowed

9.2. Retry Logic

filters:
  - name: Retry
    args:
      retries: 3
      statuses: BAD_GATEWAY,GATEWAY_TIMEOUT
      methods: GET,POST,PUT,DELETE
      backoff:
        firstBackoff: 10ms
        maxBackoff: 50ms
        factor: 2

Retry Scenarios:

  • 502 Bad Gateway - Backend unreachable

  • 504 Gateway Timeout - Backend slow to respond

  • Exponential backoff between retries

10. Security Integration

10.1. Request Headers

Outbound Headers (Angular → Gateway):

Accept-Language: en
Content-Type: application/json
X-TENANT-ID: 5  // Optional: For programmatic/API access

Tenant Resolution Headers:

The gateway supports tenant identification via the X-TENANT-ID header for programmatic access:

Header Format Example

X-TENANT-ID

Numeric tenant ID (Long)

X-TENANT-ID: 5

Priority:

  1. URL subdomain (e.g., runningclub.example.com)

  2. X-TENANT-ID header

11. Monitoring and Observability

11.1. Metrics

Gateway Metrics:

  • Request rate per route

  • Response time per route

  • Error rate per route

  • Circuit breaker status

  • Connection pool utilization

Endpoint: /management/metrics

11.2. Health Checks

Endpoint: /management/health

Response:

{
  "status": "UP",
  "components": {
    "gateway": {
      "status": "UP"
    },
    "admin-service": {
      "status": "UP",
      "details": {
        "responseTime": "45ms"
      }
    },
    "diskSpace": {
      "status": "UP"
    }
  }
}