Api
Ingestion Endpoint
The ingestion endpoint is a crucial part of our API, serving as the primary interaction point for the integration engines. It is responsible for receiving and processing HL7v2 messages from external sources, and is ready to be expanded to more types of messages.
Endpoint Details
URL: /$ingest
Method: POST
Content-Type: text/plain
Request
The ingestion endpoint expects an HL7v2 message in the body of the POST request. The source-domain
, organisation-code
, and data-type
are expected to be provided in the headers of the request. Here is an example of a request:
POST /$ingest HTTP/1.1
organisation-code: uhd
source-domain: agyleed
data-type: hl7v2
Content-Type: text/plain
MSH|^~\&|AGYLEED|R0D02|INTEGRATION-ENGINE|RDZ|20231127125907||ADT^A01|667151|P|2.4|||AL|NE
PID|1|0123456|0123456^^^NHS^HospitalNumber~9999999999^^^NHS^NhsNumber||SURNAME^NAME||19570830|M|||STREET^STREET2^POOLE^DORSET^BH15 3RS^^H||01234000000^PRN^PH~07000000000^PRN^CP|01234000000||||||||A
PV1|1|E||F||||||||||507291000000100|||||ED-AG-23-000000|||||||||||||||||||||||^^^R0D02||20231127125458
PV2|||Injury of shoulder / arm / elbow / wrist / hand|||||||||||||||||||||||||||||||||||1048071000000103
organisation-code
: The code representing the organisation sending the data.source-domain
: The domain system from which the data is being sent.data-type
: would be set by the integration engine based on what type of messages are we receiving (hl7v2/csv/etc)Content-Type
: The type of the content being sent. In this case, it istext/plain
as we are sending an HL7v2 message.
Response
The ingestion endpoint responds with a plain/text
result containing the status of the ingestion process. Here is an example of a response payload:
MSH|^~\&|DEX|QVV|domain|org|20240131084246||ACK|3d749df9-caa5-42e2-91bb-4f9a24a04c9d|P|2.4
MSA|AA|some-string|Successfully processed
Status Codes
200 OK
: The request was successful, and the data was ingested correctly.400 Bad Request
: The request was malformed or missing required data, or the data type is not supported500 Internal Server Error
: An error occurred on the server while processing the request, template not found, etc.
Template Name Building
The template name is built using the organisation-code, source-domain and data-type from the headers and resource type from the request payload.
The format is {organisation-code}_{source-domain}_{data-type}_{resourceType}
.
For example, if the source-domain is agyleed
, organisation-code is uhd
, data-type is hl7v2
and resource type is adt_a01
, the template name will be agyleed_uhd_hl7v2_adta01
.
Global Exception Handler
Overview
The Global Exception Handler is a centralized mechanism for handling exceptions in our application. It provides a consistent response structure for all unhandled exceptions, making it easier for clients to handle errors.
Implementation
The Global Exception Handler is implemented as a class that implements the IExceptionHandler
interface. It uses the ILogger
service to log exceptions and the IHostEnvironment
service to determine the current environment.
The implementation of the GlobalExceptionHandler
class is under the file src/Api/Exceptions/GlobalExceptionHandler.cs
.
In that file we have a mapping function that maps an exception to a status code and title, and a HandleAsync
method that handles the exception and returns a ProblemDetails
object.
currently the MapException
function only maps the Exception
class to a 500 status code and "Internal Server Error" title.
but we can add more mapping for other exceptions like TimeoutException, ArgumentException, etc.
private static (int statusCode, string title) MapException(Exception exception)
=> exception switch
{
_ => (StatusCodes.Status500InternalServerError, "Internal Server Error")
};
}
Enabling the Global Exception Handler
To enable the Global Exception Handler, you need to register it in the Startup
class:
public static IServiceCollection AddApi(this IServiceCollection services)
=> services.AddRequestTimeouts()
.AddGlobalExceptionHandling() // here
.AddEndpointsAndSwagger()
.AddFhirJsonSerializer()
.AddPatientSearchStrategies()
.AddFluentValidators();
private static IServiceCollection AddGlobalExceptionHandling(this IServiceCollection services) =>
services.AddExceptionHandler<GlobalExceptionHandler>()
.AddProblemDetails();
In the above code, the AddGlobalExceptionHandling
extension method is used to register the GlobalExceptionHandler
with the dependency injection container. This method is part of the DependencyInjection
class in the src/Api/DependencyInjection.cs
file.
Error Response
The Global Exception Handler returns a JSON response with a ProblemDetails
object. This object includes the status code, title, trace ID, and instance of the error.
In a development and staging environment, it also includes the detail of the error.
Here's an example of what the error response might look like in a development/staging environment:
{
"status": 500,
"title": "Internal Server Error",
"traceId": "0HLN8KNV7BB6S:00000001",
"instance": "GET /Patient?nhs-number=1234567890",
"detail": "An unhandled exception occurred."
}
In a production environment, the detail
field is omitted:
{
"status": 500,
"title": "Internal Server Error",
"traceId": "0HLN8KNV7BB6S:00000001",
"instance": "GET /api/values"
}