HSG-MCS-HS21_tapas/tapas-tasks
2021-10-18 11:45:52 +02:00
..
.mvn/wrapper Initial commit 2021-10-04 09:13:00 +02:00
src merge everything from main project 2021-10-18 11:45:52 +02:00
.editorconfig Initial commit 2021-10-04 09:13:00 +02:00
.gitignore Initial commit 2021-10-04 09:13:00 +02:00
Dockerfile bugfixes 2021-10-17 17:43:55 +02:00
mvnw Initial commit 2021-10-04 09:13:00 +02:00
mvnw.cmd Initial commit 2021-10-04 09:13:00 +02:00
pom.xml merge everything from main project 2021-10-18 11:45:52 +02:00
README.md merge everything from main project 2021-10-18 11:45:52 +02:00

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 created
  • taskType: 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 the taskStatus already in the task's representation with the value ASSIGNED
  • an operation to add to the task's representation a serviceProvider with the value tapas-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.