Skip to content

Custom Endpoints

Create custom REST endpoints in the client microservice when you need to trigger business logic from a pipeline, expose client-specific data, or integrate with external systems.

When to create a custom endpoint

  • Trigger business logic as part of a pipeline (the most common use case)
  • Provide a risk data snapshot for reporting, migration verification, or integration
  • Update or correct risk values directly (e.g. backfill a field after a migration)
  • Expose client-specific data to the front end or external systems
  • Implement CustomFormOptionsProvider for API-driven form options (see API-Driven Options)

Warning

Exposing any endpoint externally (outside the internal network) requires a DevOps infrastructure change. Coordinate with DevOps before planning any external-facing endpoint.

Creating a controller

Controllers live in the client microservice repository and follow standard Spring MVC conventions.

Example: GET endpoint

@GetMapping("/v1/client/v1/appetite-check/risk/{riskId}")
public ResponseEntity<AppetiteCheckDto> getData(@PathVariable Long riskId) {
    Risk risk = riskService.findById(riskId);
    AppetiteCheckDto dto = appetiteCheckService.getData(risk);
    return ResponseEntity.ok(dto);
}

Example: POST endpoint

@PostMapping("/v1/client/v1/appetite-check/risk-action-instance/{riskActionInstanceId}")
public ResponseEntity<Void> saveData(
    @PathVariable Long riskActionInstanceId,
    @RequestBody AppetiteCheckDto dto) {
    appetiteCheckService.save(riskActionInstanceId, dto);
    return ResponseEntity.ok().build();
}

Accessing risk data

Approach Usage
riskService.findById(riskId) Find a risk by ID using the core service
riskValueService.extractRiskValue(risk, code) Read a custom field value from the risk_value table
riskValueService.saveValue(risk, code, value) Write a custom field value to the risk_value table
Standard Spring Data repositories Query client schema tables

Updating risk values

When updating risk data from an endpoint:

  1. Retrieve the risk using riskService
  2. Use riskValueService.saveValue(risk, code, value) to write the new value
  3. Call riskService.processRisk() if downstream logic depends on the updated field
  4. Inject WebSocketService and publish the relevant event so the front end refreshes

Warning

If you update risk data without using core services, changes may not propagate correctly to front-end clients via WebSocket. Always use core update methods for fields that affect UI state.

The appetite check pattern

The appetite check is the canonical example of a client endpoint wired to a risk action. The screen meta data config's apiGet and apiPost fields point to these endpoints:

{
  "apiGet": "/v1/client/v1/appetite-check/risk-action-instance/{riskActionInstanceId}",
  "apiPost": "/v1/client/v1/appetite-check/risk-action-instance/{riskActionInstanceId}"
}
  • GET retrieves existing data to pre-populate the action pop-up when opened
  • POST saves the user's input when they complete the action

This pattern applies to all custom risk action endpoints.

Testing endpoints locally

Swagger UI

Once the client microservice starts, navigate to the Swagger UI at the local service port. New endpoints appear automatically.

Postman / REST client

All client microservice endpoints require Basic Auth. Find credentials in the local PDE configuration file (pde.dev.json) under basicAuth.username and basicAuth.password.

URL: http://localhost:{port}/v1/client/v1/{your-path}

Cron jobs (Quartz Scheduler)

The client microservice uses Quartz for scheduled jobs. To trigger a cron job immediately in development without changing the schedule:

  1. Create a temporary endpoint that injects the job class and calls execute()
  2. Call the endpoint to trigger the job immediately
  3. Remove or guard the endpoint after use

Party data

The party table stores all counterparties (brokers, cedents/insureds):

Party type Source
BROKER Sourced from configuration JSON files loaded at startup
CEDENT / INSURED Synced nightly from a secured data source via a Quartz cron job

Note

If a counterparty's name changes in the source data, the previous record is deleted and a new one created. The system cannot detect renames — this is a known limitation to communicate to clients.