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
CustomFormOptionsProviderfor 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:
- Retrieve the risk using
riskService - Use
riskValueService.saveValue(risk, code, value)to write the new value - Call
riskService.processRisk()if downstream logic depends on the updated field - Inject
WebSocketServiceand 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}"
}
GETretrieves existing data to pre-populate the action pop-up when openedPOSTsaves 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.
Cron jobs (Quartz Scheduler)¶
The client microservice uses Quartz for scheduled jobs. To trigger a cron job immediately in development without changing the schedule:
- Create a temporary endpoint that injects the job class and calls
execute() - Call the endpoint to trigger the job immediately
- 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.