A service facilitates data exchange between systems, involving requests and/or responses. An example of such a request is an API call to calculate a rate or accept a policy. A response can be a result or a notification. If the response contains data (such as a calculated rate), a result is returned in the form of a response message. However, if the response is limited to a message whether the action was successful or not, only a notification is sent. Parties can develop AFD-definitions tailored to their (web)services and functions. The AFD-definition is an XML Schema (AFD 1.0) or JSON Schema (AFD 2.0) with the specifications of the request and (if it contains data) response message of the service. With this AFD-definition, parties can easily set up their service or API.

Features of AFD 2.0 message for service request

Calling a service involves passing variables to execute specific actions. For comprehensive logging and workflow transmission, it is recommended to include the attribute functionVariant (within the entity commonFunctional) into the request, although it can be inferred from the endpoint, as well. functionVariant is associated with the code list APIVAR, encompassing all function variants within the SIVI AFS API-framework. Upon selecting the functionVariant, not only are the chosen function and underlying process conventions identified, but also the attributes and parameters necessary for executing the function.

{
	"commonFunctional": [ 
		{
			"entityType": "default",			
			"afdDefinitionName": "Goed verzekerd op weg",
			"afdDefinitionVersion": "001.00",
			"businessLine": "020",
			"porCompany": "Q001",
			"dataCatalogVersion": "46D",
			"functionVariant": "A0010"
		}
	 ],
	.....

A message may include a commonTechnical entity, which holds the technical metadata of the message. This entity is optional, but it contains some attributes, that are intended for messages related to services, such as:

  • creationDateTime – Represents the creation date and time of the message as a timestamp.
  • senderId – Identifies the calling party, granting access to the system it called.
  • accessCode – Code granting the calling party access to the system it called.
  • sessionId – Identifies the session duration between user login and logout.

The attribute creationDateTime is particularly relevant for services.

The example below illustrates a new policy request (functionVariant “A0010” means newContract).

{
	"commonFunctional": [
		{
			"entityType": "default",
			"function": "01",
			"porCompany": "Q001",
			"businessLine": "021",
			"functionVariant": "A0010",
			"afdDefinitionName": "Gemak Verzekerd Generiek AFD 2.0",
			"dataCatalogVersion": "42C",
			"afdDefinitionVersion": "001.00"
		}
	],
	"commonTechnical": [
		{
			"entityType": "default",
			"creationDateTime": "2024-02-18 08:05:19",
			"senderId": "S-HB350012",
			"receiverId": "R-BB715400",
			"accessCode": "ADCELZ",
			"sessionId": "54678IHL"
		}
	],
	"policy": [
		{
			"party": [
				{
					"entityType": "regularDriver",
					"refType": "A",
					"birthDate": "1980-08-12"
				},
				{
					"entityType": "policyholder",
					"collectionAccountIban": "NL98INGB0003856625",
					"initials": "T.I.",
					"prefixes": "van de",
					"surname": "Velden",
					"gender": "V",
					"birthDate": "1980-08-12",
					"street": "Pythagoraslaan",
					"houseNumber": "101",
					"houseNumberAddition": "A",
					"city": "Utrecht",
					"postalCode": "3584BB",
					"telephoneNumber": "0306988090",
					"email": "tvandevelden@sivi.org"
				},
				{
					"entityType": "intermediary",
					"id": "TP3679473"
				}
			],
			"object": [
				{
					"entityType": "motorVehicle",
					"fuel": "B",
					"make": "Mazda",
					"model": "CX3",
					"reportCode": "4583",
					"weightInKg": 1130,
					"licensePlate": "QQ999Q",
					"annualMileage": 20000,
					"constructionYear": 2020,
					"initialListPrice": 30000
				}
			],
			"premium": [
				{
					"entityType": "premiumDetails",
					"totalInstallmentAmount": 0,
					"insuranceTaxInstallmentAmount": 0
				}
			],
			"coverage": [
				{
					"entityType": "thirdPartyLiability",
					"coverageCode": "2001",
					"noClaimsPercentage": 55,
					"grossPremiumInstallment": 0,
					"noClaimsDiscountStepNumber": 8,
					"noClaimsDiscountInstallmentAmount": 0
				}
			],
			"entityType": "policyDetails",
			"statusType": "18",
			"renewalDate": "2025-04-01",
			"effectiveDate": "2024-04-01",
			"collectionMethod": "I",
			"externalIndicative": "VP4321546",
			"paymentTermInMonths": 3,
			"renewalCommissionPercentage": 10,
			"numberOfClaimFreeYearsOnStatement": 2
		}
	]
}

Features of AFD 2.0 message for service result

Within the SIVI AFS API-framework, the principle is that the return message includes all provided data. However, there are exceptions. For instance, in the ‘status’ function variant, only the status is returned. The attributes returned depend on the function and domain.

Information regarding the transaction process is found in the ‘process’ entity, within the entityType ‘transaction’. Key attributes include:

  • statusType: Code indicating the result of the request (e.g., code 0 = rejected).
  • statusExplanation: Additional information accompanying the statusType code. In case of rejection, it provides details on why the request was rejected.

The following example illustrates the response to a new policy request.

{
	"commonFunctional": [
		{
			"entityType": "default",
			"function": "01",
			"porCompany": "Q001",
			"businessLine": "021",
			"functionVariant": "A0010",
			"afdDefinitionName": "Gemak Verzekerd Generiek AFD 2.0",
			"dataCatalogVersion": "42C",
			"afdDefinitionVersion": "001.00"
		}
	],
	"commonTechnical": [
		{
			"entityType": "default",
			"creationDateTime": "2024-02-18 08:05:19",
			"senderId": "S-HB350012",
			"accessCode": "ADCELZ",
			"sessionId": "54678IHL"
		}
	],
	"policy": [
		{
			"party": [
				{
					"entityType": "regularDriver",
					"refType": "A",
					"birthDate": "1980-08-12"
				},
				{
					"entityType": "policyholder",
					"collectionAccountIban": "NL98INGB0003856625",
					"initials": "T.I.",
					"prefixes": "van de",
					"surname": "Velden",
					"gender": "V",
					"birthDate": "1980-08-12",
					"street": "Pythagoraslaan",
					"houseNumber": "101",
					"houseNumberAddition": "A",
					"city": "Utrecht",
					"postalCode": "3584BB",
					"telephoneNumber": "0306988090",
					"email": "tvandevelden@sivi.org"
				},
				{
					"entityType": "intermediary",
					"id": "TP3679473"
				}
			],
			"object": [
				{
					"entityType": "motorVehicle",
					"fuel": "B",
					"make": "Mazda",
					"model": "CX3",
					"reportCode": "4583",
					"weightInKg": 1130,
					"licensePlate": "QQ999Q",
					"annualMileage": 20000,
					"constructionYear": 2020,
					"initialListPrice": 30000
				}
			],
			"premium": [
				{
					"entityType": "premiumDetails",
					"totalInstallmentAmount": 26.91,
					"insuranceTaxInstallmentAmount": 4.67
				}
			],
			"coverage": [
				{
					"entityType": "thirdPartyLiability",
					"coverageCode": "2001",
					"noClaimsPercentage": 55,
					"grossPremiumInstallment": 22.24,
					"noClaimsDiscountStepNumber": 8,
					"noClaimsDiscountInstallmentAmount": 27.01 
				}
			],
			"entityType": "policyDetails",
			"statusType": "18",
			"renewalDate": "2025-04-01",
			"effectiveDate": "2024-04-01",
			"collectionMethod": "I",
			"externalIndicative": "VP4321546",
			"paymentTermInMonths": 3,
			"renewalCommissionPercentage": 10,
			"numberOfClaimFreeYearsOnStatement": 2
		}
	],
	"process": [
		{
			"process": [
				{
					"entityType":"StatusNotification",
					"statusExplanation": "Polis is geaccepteerd"
				}
			],
			"entityType": "transaction",
			"statusType": "8",
			"statusTypeExplanation": "Geaccepteerd"
		}
	]
}

Error responses

In certain scenarios, a service call may fail due to a technical issue, such as a message error or an error encountered during service handling. In such cases, the returned payload consists solely of an error entity containing attributes describing the error message. These attributes, including the HTTP status code, may be displayed to aid in error handling.

The following attributes are available for the entity error:

  • httpStatus: The http status code retrieved from the response header, included here for easier error retrieval/definition.
  • errorCode: Specifies the error message. API providers can define their own codes within the range 1000 – 9999.
  • errorDescription: Additional text providing a description of the error message.

For further details on the handling of technical issues, please refer to Error messages SOAP and REST.

Not only technical errors, also functional errors can be applicable. Functional error handling can be managed with process.transaction and process.statusNotification (AFD 2.0) or the XG/XM entity (AFD 1.0).

The example below is part of a message, where the message is technically correct, but the statusType shows the action was aborted.

{
	...
	"process": [
		{
			"process": [
				{
					"entityType":"StatusNotification",
					"statusExplanation": "Polis is niet verwerkt, proces afgebroken"
				}
			],
			"entityType": "transaction",
			"statusType": "15",
			"statusTypeExplanation": "Proces afgebroken"
		}
	]
	...
}

REST APIs vs. event-driven APIs

APIs play an important role in data exchange for services. SIVI elaborated this primarily for REST APIs and event-driven APIs, although other protocols can be used for AFD, as well. The main difference between REST APIs and event-driven APIs is the way they manage data exchange and interactions.

  • RESTful API is based on the request-response model, where the client explicitly asks for information or actions, often used in traditional web and mobile applications.
  • Eventful API is based on event-driven communication, where events are generated and other systems respond to them, suitable for real-time systems and distributed architectures.

Traditional APIs, such as REST APIs with JSON, operate according to a request-response pattern. The client sends a request to the server and then waits for a response. This pattern can be synchronous or asynchronous: in a synchronous approach, the client receives an immediate response, while in an asynchronous approach, some delay is possible. REST APIs are primarily focused on retrieving information, where the client explicitly requests specific data and the server provides it.

Event-driven APIs operate differently. They use events, such as ‘policy accepted’ or ‘address changed’. Instead of an explicit request, a party sends an event message when a change occurs. The communication is by definition asynchronous: no direct response is expected, only an acknowledgement of receipt. These APIs are designed to report changes, not to request information. Event-driven APIs offer enhanced efficiency and scalability, reducing total ownership costs. They are particularly useful when a party simply wants to indicate that something has happened, without needing direct feedback.

Efficient use for relevant change
Event-driven APIs function within an event-driven architecture, in which events drive communication between systems or applications. This architecture is particularly suitable for environments where status changes occur frequently and systems must remain disconnected. The sending party shares an event, such as ‘policy accepted’, and other systems receive this without any direct dependencies between the systems. In fact, the sender of the notification does not care what the recipient does with the notification. This makes the solution more scalable and efficient, especially in case of large amounts of data or the need for real-time updates.

Unlike REST APIs, which require a client to periodically retrieve data (polling), an event-driven API automatically sends a message whenever a relevant change occurs. This eliminates the need for continuous polling or batch processing.

Technical operation of event-driven APIs
In case of an event-driven API, the sending party publishes a message on a channel. Receiving parties that are subscribed to this channel automatically receive these messages. The distribution of messages is handled by a message broker: an infrastructure that is responsible for routing events to the correct recipients. Systems like RabbitMQ, Kafka of AWS SNS/SQS can be used for this.

The table below shows a concise comparison between REST and event-driven APIs.

REST API Event-driven API
Focused on direct (synchronous) data exchange, but also supports asynchronous communication Particularly designed for asynchronous communication via a publish-subscribe model
Client (request sender) initiates request to server Systems respond to events that are automatically published and sent to subscribed recipients
Higher chance of increased network traffic due to frequent requests (e.g. polling) Reduced network load as messages are only sent when relevant events occur
Stateless: all context information must be sent again with each request Less dependent on stateless design; events are shared with context and processed efficiently
Lower initial development costs due to simpler design and limited infrastructure requirements Higher initial development costs due to the need for a message broker and more complex test scenarios

SIVI AFS API framework
In the current SIVI AFS API framework, REST API is the principle. This means that the function table is set up with request and response in mind and uses a path and an endpoint. In the case of event-driven APIs a channel applies, instead. The channel in an event-driven API is comparable to an ‘endpoint’ (a REST API term), where the messages are published. The receiving party can subscribe to a channel to receive updates about specific types of events, such as ‘new policy’ or ‘loan adjusted’. This subscription is technically set up using a message broker, such as Kafka or RabbitMQ.
Another important difference with the REST approach is that a channel is usually set up ‘broader’. The difference between different types of events, such as a new, changed or terminated policy, is not part of the channel itself. In case of an endpoint, the difference is part of the endpoint: e.g. \policies\new for new policies compared to \policies\changed for mutated policies. The recipient also likes to receive these details (for example new or changed) directly with event-driven APIs, without having to unpack the message itself. Metadata in the parameters can provide these details. These parameters are added to the message and indicate, for example, whether it concerns a new or amended policy.

OpenAPI Specifcation

OpenAPI Specification (OAS) is an API description format for REST APIs. An OpenAPI file allows the user to describe the entire API, including:

  • Available endpoints (example: /users) and operations on each endpoint (GET /users, POST /users).
  • Operation parameters input and output for each operation.
  • Server objects.
  • Security requirements.
  • Contact information, license, terms of use, and other information.

OpenAPI specifications can be written in YAML or JSON. The format is easy to learn and readable to both humans and machines.


Figure 3.3-1 Example of OpenAPI specifications (source: https://swagger.io/specification/)

More information about OpenAPI specification can be found on the website of Swagger.

More information about the use of APIs within SIVI AFS is described in chapter Domain specific functions.

AsyncAPI
In the context of event-driven APIs, developers can utilize AsyncAPI, a framework designed for describing the specifications of event-driven APIs. Similar to OpenAPI, it helps developers, architects, and analysts better understand, design, and implement APIs. A key advantage of AsyncAPI is its support for multiple communication protocols, such as Apache Kafka, RabbitMQ, and WebSocket. This flexibility allows organizations to choose the technology that best fits their infrastructure while maintaining consistent specifications.

Feedback

Thanks for your feedback.

Post your comment on this topic.

Please do not use this for support questions.
If you have any support questions, do not hesitate to contact us.

Post Comment