API Reference
Clamp API
The following section covers API documentation for Clamp's REST API, which ships with endpoints handling workflow creation, triggering a service request, and so forth.
Swagger
If you're someone who likes to get their hands dirty immediately, maybe you would like to check out this Swagger link to try out the APIs.
Workflows
Creation
Workflows are created in Clamp by making a POST request to its /workflow API endpoint.
Here's a sample payload: (Click to expand)
```
{
"name": "process_claim",
"description": "processing of medical claim",
"steps": [
{
"name": "user_authentication",
"mode": "HTTP",
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/f4ee8258-49b1-4579-a8c2-5881a0c65206"
}
},
{
"name": "user_authorization",
"mode": "HTTP",
"transform": true,
"requestTransform": {
"spec": {
"username": "user_authentication.response.username",
"userId": "user_authentication.response.id"
}
},
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/d9f2e6d1-3100-4ffb-88a4-633e89e1b99c"
}
},
{
"name": "get_user_details",
"mode": "HTTP",
"transform": true,
"requestTransform": {
"spec": {
"username": "user_authentication.response.username",
"userId": "user_authentication.response.id",
"roles": "user_authorization.response.roles"
}
},
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/0df407a1-d4ea-41b3-bf2d-31f3c0fe03b5"
}
},
{
"name": "create_claim",
"mode": "HTTP",
"transform": true,
"requestTransform": {
"spec": {
"claimDetails": "user_authentication.request.claimDetails",
"userId": "user_authentication.response.id",
"existingPolicies": "get_user_details.response.policyDetails"
}
},
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/c73e40b4-a044-44bd-931a-d0f08d58f0d3"
}
},
{
"name": "submit_motor_claim",
"when": "user_authentication.request.claimDetails.claimType == 'MOTOR'",
"mode": "AMQP",
"transform": true,
"requestTransform": {
"spec": {
"claimId": "create_claim.response.claimId",
"userId": "user_authentication.response.id",
"claimStatus": "create_claim.response.claimStatus",
"claimType": "user_authentication.request.claimDetails.claimType",
"claimDate": "create_claim.response.claimDate",
"policyId": "create_claim.response.policyId",
"garageId": "create_claim.response.garageId",
"inspectorDetails": "create_claim.response.inspectorDetails"
}
},
"val": {
"connection_url": "amqp://clamp:clampdev!@172.31.0.152:5672/",
"queue_name": "clamp_queue",
"content_type": "text/plain"
}
},
{
"name": "submit_medical_claim",
"when": "user_authentication.request.claimDetails.claimType == 'MEDICAL'",
"mode": "KAFKA",
"transform": true,
"requestTransform": {
"spec": {
"claimId": "create_claim.response.claimId",
"userId": "user_authentication.response.id",
"claimStatus": "submit_medical_claim.request.claimStatus",
"claimType": "user_authentication.request.claimDetails.claimType",
"claimDate": "create_claim.response.claimDate",
"policyId": "create_claim.response.policyId",
"garageId": "create_claim.response.garageId",
"inspectorDetails": "create_claim.response.inspectorDetails"
}
},
"val": {
"connection_url": "172.31.0.152:9092",
"topic_name": "clamp_topic"
}
},
{
"name": "update_approved_claim",
"when": "update_approved_claim.request.claimStatus == 'APPROVED'",
"mode": "HTTP",
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/39528702-f29f-4a87-98e7-55b43c81fed3"
}
},
{
"name": "update_reject_claim",
"when": "update_reject_claim.request.claimStatus == 'REJECTED'",
"mode": "HTTP",
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/b0ab4d1c-263b-41f5-9888-c8913160c20f"
}
},
{
"name": "process_disbursement",
"when": "update_approved_claim.request.claimStatus == 'APPROVED'",
"mode": "HTTP",
"transform": true,
"requestTransform": {
"spec": {
"claimId": "create_claim.response.claimId",
"userId": "user_authentication.response.id",
"claimStatus": "process_disbursement.request.claimStatus",
"approvedAmount": "process_disbursement.request.reviewerDetails.approvedAmount",
"reviewerId": "process_disbursement.request.reviewerDetails.reviewerId",
"reviewerDate": "process_disbursement.request.reviewerDetails.reviewDate"
}
},
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/a2a9bb05-f043-4a6e-b513-0377902bd85d"
}
}
]
}
```
Workflow Metadata
There's some basic metadata that needs to be defined when a workflow is created. The following attributes are mandatory and must be present in the request:
nameis the unique identifier for any workflow. It is recommended that you keep this short and name every workflow in a consistent manner. Camel case is recommended, but not mandatory. You could hyphenate between words or use underscores, or choose any other convention, as long as you choose one and stick with it. This field does not accept spaces.descriptionis typically a brief title describing what the workflow is for.stepsare used to describe the workflow in terms of service calls and payload transformations. Steps support simple branching strategies, as well as rollback strategies for error scenarios. See more on defining steps below.
Defining Steps
The following section covers how to define steps in your workflow specification. Here's a sample step:
{
"name": "submit motor claim",
"when": "user_authentication.request.claimDetails.claimType == 'MOTOR'",
"mode": "AMQP",
"transform" : true,
"requestTransform": {
"spec":{
"claimId": "create_claim.response.claimId",
"userId": "user_authentication.response.id",
"claimStatus": "create_claim.response.claimStatus",
"claimType": "user_authentication.request.claimDetails.claimType",
"claimDate": "create_claim.response.claimDate",
"policyId": "create_claim.response.policyId",
"garageId":"create_claim.response.garageId",
"inspectorDetails":"create_claim.response.inspectorDetails"
}
},
"val": {
"connection_url": "amqp://clamp:clampdev!@172.31.0.152:5672/",
"queue_name": "clamp_queue",
"content_type": "text/plain"
}
}
There's some basic metadata that needs to be defined for a step.
nameis the unique identifier for a step in a workflow. It is recommended that you keep this short. Camel case is recommended, but not mandatory. You could hyphenate between words or use underscores, or choose any other convention, as long as you choose one and stick with it. This field does not accept spaces.modespecifies what communication mode it needs to use. It supports HTTP / KAFKA / AMQP.valis the connection config to use for communication. Below are configs specific to each modes.HTTP"val": { "method": "POST", "url": "https://run.mocky.io/v3/f4ee8258-49b1-4579-a8c2-5881a0c65206", "headers": "Content-Type:application/json" }AMQP"val": { "connection_url": "amqp://clamp:clampdev!@172.31.0.152:5672/", "queue_name": "clamp_queue", "content_type": "text/plain" }KAFKA"val": { "connection_url": "172.31.0.152:9092", "topic_name": "clamp_topic" }
whenis used to specify the condition based on which the step execution depends. The possible options to use for comparision are hererequestTransformis used for transforming the request object to the step.transformneed to be enabled to apply the transformations.Context objectcan be used in bothwhenandrequestTransform. The context object can be accessed by directly specifying thestep_nameand then specify whetherrequestorresponseand specify the key to access it. Ex:step_name.response.key. It can be nested to any level likestep_name.response.key1.key1a
View Workflow
Once a workflow is defined, you can view the structure and metadata of the workflow by performing a GET request to the /workflow/{name} endpoint for Clamp. For example, if your workflow was called mtcReq and Clamp was running on http://54.149.76.62:8642, you would make the following cURL request:
curl http://54.149.76.62:8642/workflow/process_claim
This should return a response as below:(Click here to expand)
{
"id": "348",
"name": "process_claim",
"description": "processing of medical claim",
"enabled": true,
"created_at": "2020-09-14T12:08:37.989947Z",
"updated_at": "0001-01-01T00:00:00Z",
"steps": [
{
"id": 1,
"name": "user_authentication",
"type": "SYNC",
"mode": "HTTP",
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/f4ee8258-49b1-4579-a8c2-5881a0c65206",
"headers": ""
},
"transform": false,
"enabled": false,
"when": "",
"transformFormat": "",
"requestTransform": null,
"onFailure": null
},
{
"id": 2,
"name": "user_authorization",
"type": "SYNC",
"mode": "HTTP",
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/d9f2e6d1-3100-4ffb-88a4-633e89e1b99c",
"headers": ""
},
"transform": true,
"enabled": false,
"when": "",
"transformFormat": "",
"requestTransform": {
"spec": {
"userId": "user_authentication.response.id",
"username": "user_authentication.response.username"
}
},
"onFailure": null
},
...
...
{
"id": 8,
"name": "update_reject_claim",
"type": "SYNC",
"mode": "HTTP",
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/b0ab4d1c-263b-41f5-9888-c8913160c20f",
"headers": ""
},
"transform": false,
"enabled": false,
"when": "update_reject_claim.request.claimStatus == 'REJECTED'",
"transformFormat": "",
"requestTransform": null,
"onFailure": null
},
{
"id": 9,
"name": "process_disbursement",
"type": "SYNC",
"mode": "HTTP",
"val": {
"method": "POST",
"url": "https://run.mocky.io/v3/a2a9bb05-f043-4a6e-b513-0377902bd85d",
"headers": ""
},
"transform": true,
"enabled": false,
"when": "update_approved_claim.request.claimStatus == 'APPROVED'",
"transformFormat": "",
"requestTransform": {
"spec": {
"approvedAmount": "process_disbursement.request.reviewerDetails.approvedAmount",
"claimId": "create_claim.response.claimId",
"claimStatus": "process_disbursement.request.claimStatus",
"reviewerDate": "process_disbursement.request.reviewerDetails.reviewDate",
"reviewerId": "process_disbursement.request.reviewerDetails.reviewerId",
"userId": "user_authentication.response.id"
}
},
"onFailure": null
}
]
}
Service Requests
A service request essentially tells Clamp to execute a particular workflow. Depending upon the workflow, it may or may not require a request body to go along with it. Let us take the example of process_claim, the workflow we created in the above sections.
Creation
By making a POST request on /serviceRequest/process_claim, we can instruct Clamp to start the process_claim workflow. If our workflow requires an initial payload, we can send it in the request body.
Request:
curl -X POST 'http://54.149.76.62:8642/serviceRequest/process_claim' \
--header 'Content-Type: application/json' \
--data-raw '{
"userDetails" :{
"username": "xyz",
"password": "***",
"channel": "web"
},
"claimDetails":{
"claimType":"MOTOR",
"claimDate":"23/06/2020",
"policyId":"908",
"garageId":"5000",
"supportingDocuments":""
}
}'
The above request will trigger the process_claim workflow with the following initial payload:
{
"userDetails" :{
"username": "xyz",
"password": "***",
"channel": "web"
},
"claimDetails":{
"claimType":"MOTOR",
"claimDate":"23/06/2020",
"policyId":"908",
"garageId":"5000",
"supportingDocuments":""
}
}
Response:
{
"pollUrl": "/serviceRequest/6102fa39-d209-4b98-8c75-d9f2ef9aa791",
"status": "NEW",
"serviceRequestId": "6102fa39-d209-4b98-8c75-d9f2ef9aa791"
}}
- The
pollUrlwill contain theGETendpoint which needs to be polled to monitor the status of every service request. - The
serviceRequestIdis the unique identifier for a service request. - The
statusfield will contain the completion status for the service request.
Check Status
The status of a service request can be polled by making a GET request on the /serviceRequest/{id} endpoint, where the {id} parameter is the service request ID obtained during creation. Hence, the following request:
curl http://54.149.76.62:8642/serviceRequest/6102fa39-d209-4b98-8c75-d9f2ef9aa791
should respond back with the status of service request "6102fa39-d209-4b98-8c75-d9f2ef9aa791", which would look as follows:
"service_request_id": "6102fa39-d209-4b98-8c75-d9f2ef9aa791",
"workflow_name": "process_claim",
"status": "COMPLETED",
"total_time_in_ms": 170382,
"steps": [
{
"id": 1,
"name": "user_authentication",
"status": "STARTED",
"time_taken": 0,
"payload": {
"request": {
"claimDetails": {
"claimDate": "23/06/2020",
"claimType": "MOTOR",
"garageId": "5000",
"policyId": "908",
"supportingDocuments": ""
},
"userDetails": {
"channel": "web",
"password": "jungle-green-t0p!",
"username": "shambhu.shikari"
}
},
"response": null
}
},
{
"id": 1,
"name": "user_authentication",
"status": "COMPLETED",
"time_taken": 798,
"payload": {
"request": {
"claimDetails": {
"claimDate": "23/06/2020",
"claimType": "MOTOR",
"garageId": "5000",
"policyId": "908",
"supportingDocuments": ""
},
"userDetails": {
"channel": "web",
"password": "jungle-green-t0p!",
"username": "shambhu.shikari"
}
},
"response": {
"id": "1234567890",
"name": "Shambhu Shikari",
"username": "shambhu.shikari"
}
}
},
...
...
{
"id": 9,
"name": "process_disbursement",
"status": "STARTED",
"time_taken": 0,
"payload": {
"request": {
"approvedAmount": "5000",
"claimId": "90990908324",
"claimStatus": "APPROVED",
"reviewerDate": "2020 Jun 23 00:00:00.000 IST",
"reviewerId": "12924",
"userId": "1234567890"
},
"response": null
}
},
{
"id": 9,
"name": "process_disbursement",
"status": "COMPLETED",
"time_taken": 514,
"payload": {
"request": {
"approvedAmount": "5000",
"claimId": "90990908324",
"claimStatus": "APPROVED",
"reviewerDate": "2020 Jun 23 00:00:00.000 IST",
"reviewerId": "12924",
"userId": "1234567890"
},
"response": {
"claimId": "90990908324",
"disbursedAmount": "5000",
"disbursementDate": "2020 Jun 23 00:00:00.000 IST",
"disbursementRefId": "234234434",
"partyDetails": {
"partyId": "23432431",
"partyName": "Apple Auto"
},
"paymentInstrumentId": "CHEQUE",
"userId": "1234567890"
}
}
}
],
"reason": ""
}
- The
statusfield will contain the completion status for the service request. It will containIN_PROGRESS/COMPLETED total_time_in_mswill contain the time taken in ms to execute the complete workflowstepswill contain step level status, it contains both the request/response that is sent/received for each step.- In each step in
stepsthestatusdefines the state of each step it went through. The possible values areSTARTED/COMPLETED/SKIPPED/FAILED - The step status will be
SKIPPEDif thewhencondition is not met.
Send Response
When an async step gets executed, the response for the step needs to be sent explicitly to clamp. The response can be sent back using an HTTP API or through AMQP / Kafka queue.
HTTP
By making a POST request on
/stepResponse, we can send response to Clamp. The response can be sent in below format.Request:
curl -X POST 'http://54.149.76.62:8642/stepResponse' \ --header 'Content-Type: application/json' \ --data-raw '{ "serviceRequestId": "{{serviceRequestId}}", "stepId": 5, "response": { "claimId": "90990908324", ... "notes": "Inspection not required approved based on documentation. CASHLESS" } } }'The above request will trigger the workflow to resume execution.
- When an async step gets executed, clamp sends the current id of the service request in the request body. The downstream service needs to send back the same serviceRequestId back in the response to continue the same service request.
- The
stepIdis the next step id which needs to be executed. The value of this will also be sent as request to downstream services. - The
responsefield should contain the respective json response that needs to be sent back.
AMQP / KAFKA
The reponse can be sent back through AMQP / KAFKA. Clamp listens to specific topic in both AMQP / KAFKA.
clamp_steps_responseis the topic name to which the below response can be sent.{ "serviceRequestId": "{{serviceRequestId}}", "stepId": 5, "response": { "claimId": "90990908324", ... "notes": "Inspection not required approved based on documentation. CASHLESS" } }