6.8 KiB
tapas-tasks
Micro-service for Managing Tasks in a Task List implemented following Hexagonal Architecture.
Based on examples from book "Get Your Hands Dirty on Clean Architecture" by Tom Hombergs
Technologies: Java, Spring Boot, Maven
Note: this repository contains an EditorConfig file (.editorconfig
)
with default editor settings. EditorConfig is supported out-of-the-box by the IntelliJ IDE. To help maintain
consistent code styles, we recommend to reuse this editor configuration file in all your services.
HTTP API Overview
The code we provide includes a minimalistic uniform HTTP API for (i) creating a new task, (ii) retrieving a representation of the current state of a task, and (iii) patching the representation of a task, which is mapped to a domain/integration event.
The representations exchanged with the API use two media types:
- a JSON-based format for task with the media type
application/task+json
; this media type is defined in the context of our project, but could be registered with IANA to promote interoperability (see TaskJsonRepresentation for more details) - the JSON Patch format with the registered media type
application/json-patch+json
, which is also a JSON-based format (see sample HTTP requests below).
For further developing and working with your HTTP API, we recommend to use Postman.
Creating a new task
A new task is created via an HTTP POST
request to the /tasks/
endpoint. The body of the request
must include a representation of the task to be created using the content type application/task+json
defined in the context of this project. A valid representation must include at least two required fields
(see TaskJsonRepresentation
for more details):
taskName
: a string that represents the name of the task to be createdtaskType
: a string that represents the type of the task to be created
A sample HTTP request with curl
:
curl -i --location --request POST 'http://localhost:8081/tasks/' \
--header 'Content-Type: application/task+json' \
--data-raw '{
"taskName" : "task1",
"taskType" : "computation",
"originalTaskUri" : "http://example.org",
"inputData" : "1+1"
}'
HTTP/1.1 201
Location: http://localhost:8081/tasks/cef2fa9d-367b-4e7f-bf06-3b1fea35f354
Content-Type: application/task+json
Content-Length: 170
Date: Sun, 17 Oct 2021 21:03:34 GMT
{
"taskId":"cef2fa9d-367b-4e7f-bf06-3b1fea35f354",
"taskName":"task1",
"taskType":"computation",
"taskStatus":"OPEN",
"originalTaskUri":"http://example.org",
"inputData":"1+1"
}
If the task is created successfuly, a 201 Created
status code is returned together with a
representation of the created task. The response also includes a Location
header filed that points
to the URI of the newly created task.
Retrieving a task
The representation of a task is retrieved via an HTTP GET
request to the URI of task.
A sample HTTP request with curl
:
curl -i --location --request GET 'http://localhost:8081/tasks/cef2fa9d-367b-4e7f-bf06-3b1fea35f354'
HTTP/1.1 200
Content-Type: application/task+json
Content-Length: 170
Date: Sun, 17 Oct 2021 21:07:04 GMT
{
"taskId":"cef2fa9d-367b-4e7f-bf06-3b1fea35f354",
"taskName":"task1",
"taskType":"computation",
"taskStatus":"OPEN",
"originalTaskUri":"http://example.org",
"inputData":"1+1"
}
Patching a task
REST emphasizes the generality of interfaces to promote uniform interaction. For instance, we can use
the HTTP PATCH
method to implement fine-grained updates to the representational state of a task, which
may translate to various domain/integration events. However, to conform to the uniform interface
contraint in REST, any such updates have to rely on standard knowledge — and thus to hide away the
implementation details of our service.
In addition to the application/task+json
media type we defined for our uniform HTTP API, a standard
representation format we can use to specify fine-grained updates to the representation of tasks
is JSON Patch. In what follow, we provide a few examples of HTTP PATCH
requests.
For further details on the JSON Patch format, see also RFC 6902).
Changing the status of a task from OPEN to ASSIGNED
Sample HTTP request that assigns the previously created task to group tapas-group1
:
curl -i --location --request PATCH 'http://localhost:8081/tasks/cef2fa9d-367b-4e7f-bf06-3b1fea35f354' \
--header 'Content-Type: application/json-patch+json' \
--data-raw '[ {"op" : "replace", "path": "/taskStatus", "value" : "ASSIGNED" },
{"op" : "add", "path": "/serviceProvider", "value" : "tapas-group1" } ]'
HTTP/1.1 200
Content-Type: application/task+json
Content-Length: 207
Date: Sun, 17 Oct 2021 21:20:58 GMT
{
"taskId":"cef2fa9d-367b-4e7f-bf06-3b1fea35f354",
"taskName":"task1",
"taskType":"computation",
"taskStatus":"ASSIGNED",
"originalTaskUri":"http://example.org",
"serviceProvider":"tapas-group1",
"inputData":"1+1"
}
In this example, the requested patch includes two JSON Patch operations:
- an operation to
replace
thetaskStatus
already in the task's representation with the valueASSIGNED
- an operation to
add
to the task's representation aserviceProvider
with the valuetapas-group1
Internally, this request is mapped to a
TaskAssignedEvent.
The HTTP response returns a 200 OK
status code together with the updated representation of the task.
Changing the status of a task from to EXECUTED
Sample HTTP request that changes the status of the task to EXECUTED
and adds an output result:
curl -i --location --request PATCH 'http://localhost:8081/tasks/cef2fa9d-367b-4e7f-bf06-3b1fea35f354' \
--header 'Content-Type: application/json-patch+json' \
--data-raw '[ {"op" : "replace", "path": "/taskStatus", "value" : "EXECUTED" },
{"op" : "add", "path": "/outputData", "value" : "2" } ]'
HTTP/1.1 200
Content-Type: application/task+json
Content-Length: 224
Date: Sun, 17 Oct 2021 21:32:25 GMT
{
"taskId":"cef2fa9d-367b-4e7f-bf06-3b1fea35f354",
"taskName":"task1",
"taskType":"computation",
"taskStatus":"EXECUTED",
"originalTaskUri":"http://example.org",
"serviceProvider":"tapas-group1",
"inputData":"1+1",
"outputData":"2"
}
Internally, this request is mapped to a
TaskExecutedEvent.
The HTTP response returns a 200 OK
status code together with the updated representation of the task.