Framework and build tools
+For this project I chose to use Spring Boot alongside Gradle.
+Purpose
+Small assignment to assess your capacity to execute a specific request
+It is taking into account some of the software engineering aspects beyond programming, like (non-exhaustive list):
+-
+
-
+
Packaging
+
+ -
+
Layering
+
+ -
+
Error management
+
+ -
+
Documentation
+
+ -
+
Deployment aspects
+
+ -
+
Testing
+
+
This is a contrived example, especially designed to make the candidates exercise a deeper knowledge of the framework, going beyond simple tutorials that can be found online.
+Credits (Purpose section) : B2Boost
+Api documentation
+In the following document you will find a simple documentation of the API. +Most of the following sections have been generated with Spring Rest Docs.
+The partner resource
+Field | +Type | +Semantics | +Example | +
---|---|---|---|
id |
+long |
+The database id of the partner |
+1 |
+
name |
+string |
+"The name of the partner" |
+"B2Boost" |
+
reference |
+string |
+The unique reference of the partner |
+"xxxxx" |
+
locale |
+string |
+A valid Locale of the partner |
+"en_BE" |
+
expirationTime |
+string |
+The ISO-8601 UTC date time when the partner is going to expire |
+"2022-11-24 17:46:00+01:00" |
+
Accessing all the partners GET endpoint
+A GET
request is used to access all the partners read.
Request structure
+GET /partners HTTP/1.1
+Host: localhost:8080
+Example response
+HTTP/1.1 200 OK
+Content-Type: application/json
+Content-Length: 1359
+
+{
+ "content": [
+ {
+ "id": 1,
+ "name": "B2boost",
+ "reference": "FYI1",
+ "locale": "en_BE",
+ "expirationTime": "2022-11-24 17:46:00+01"
+ },
+ {
+ "id": 2,
+ "name": "Proximus",
+ "reference": "FYI2",
+ "locale": "en_BE",
+ "expirationTime": "2022-11-24 17:46:00+01"
+ },
+
+ // more json elements...
+
+ {
+ "id": 10,
+ "name": "Cisco",
+ "reference": "FYI10",
+ "locale": "en_US",
+ "expirationTime": "2022-11-24 17:46:00-04"
+ }
+ ],
+ "pageable": {
+ "sort": {
+ "empty": true,
+ "sorted": false,
+ "unsorted": true
+ },
+ "offset": 0,
+ "pageNumber": 0,
+ "pageSize": 10,
+ "paged": true,
+ "unpaged": false
+ },
+ "totalPages": 2,
+ "totalElements": 12,
+ "last": false,
+ "size": 10,
+ "number": 0,
+ "sort": {
+ "empty": true,
+ "sorted": false,
+ "unsorted": true
+ },
+ "first": true,
+ "numberOfElements": 10,
+ "empty": false
+}
+
+ Note
+ |
++response body within content json array and pagination infos within pageable json object + | +
CURL request
+$ curl 'http://localhost:8080/partners' -i -X GET
+Pagination parameters
+Parameter | +Description | +
---|---|
|
+offset in the resultset to paginate to (default value is 0) |
+
|
+Window pagination size (default value is 10) |
+
Exemple CURL request with pagination parameters
+$ curl --location --request GET 'http://localhost:8080/partners?from=0&size=4'
+Accessing the partner GET endpoint
+A GET
request is used to access the partner read.
Request structure
+GET /partner/1 HTTP/1.1
+Host: localhost:8080
+Path Parameters
+Parameter | +Description | +
---|---|
|
+id of partner to be searched |
+
Example response
+HTTP/1.1 200 OK
+Content-Type: application/json
+Content-Length: 129
+
+{
+ "id" : 1,
+ "name" : "B2boost",
+ "reference" : "FYI1",
+ "locale" : "en_BE",
+ "expirationTime" : "2022-11-24 17:46:00+01"
+}
+CURL request
+$ curl 'http://localhost:8080/partner/1' -i -X GET
+Example GET request with errors
+Example with invalid value for id
+$ curl --location --request GET 'http://localhost:8080/partner/-1'
+Response
+{
+ "code": 500,
+ "message": "getPartnerById.Id: must be greater than or equal to 1"
+}
+
+ Note
+ |
++The Min value for id is 1 + | +
Example partner not found
+$ curl --location --request GET 'http://localhost:8080/partner/3000'
+Response
+{
+ "code": 404,
+ "message": "Partner with id 3000 not found!"
+}
+Accessing the partner POST endpoint
+A POST
request is used to add a partner resource.
Request structure
+POST /partner HTTP/1.1
+Content-Type: application/json
+Content-Length: 117
+Host: localhost:8080
+
+{
+ "reference" : "FYI25",
+ "expirationTime" : "2013-10-03T12:18:46+01:00",
+ "name" : "UPS",
+ "locale" : "en_BE"
+}
+Example response
+HTTP/1.1 201 Created
+Content-Type: application/json
+Content-Length: 130
+
+{
+ "id" : 13,
+ "name" : "UPS",
+ "reference" : "FYI25",
+ "locale" : "en_BE",
+ "expirationTime" : "2013-10-03T12:18:46+01:00"
+}
+CURL request
+$ curl 'http://localhost:8080/partner' -i -X POST \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "reference" : "FYI25",
+ "expirationTime" : "2013-10-03T12:18:46+01:00",
+ "name" : "UPS",
+ "locale" : "en_BE"
+}'
+Example POST request with errors
+Example with error on create with wrong date format
+$ curl --location --request POST 'http://localhost:8080/partner' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "name": "UPS",
+ "reference": "FYI15",
+ "locale": "en_BE",
+ "expirationTime": "2017-10-03T12:18:46"
+}'
+Response
+{
+ "code": 400,
+ "message": "Date 2017-10-03T12:18:46 is an invalid ISO-8601 UTC date time! Should be something like 2017-10-03T12:18:46+00:00"
+}
+
+ Note
+ |
++Here the UTC timezone is missing + | +
Example with error on create with invalid locale
+$ curl --location --request POST 'http://localhost:8080/partner' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "name": "UPS",
+ "reference": "FYI15",
+ "locale": "en_BEE",
+ "expirationTime": "2017-10-03T12:18:46+08:00"
+}'
+Response
+{
+ "code": 400,
+ "message": "Locale en_BEE is an invalid Locale!"
+}
+
+ Note
+ |
++Here the locale should be en_BE + | +
Accessing the partner PUT endpoint
+A PUT
request is used to update a partner resource.
Request structure
+PUT /partner/3 HTTP/1.1
+Content-Type: application/json
+Content-Length: 97
+Host: localhost:8080
+
+{"reference":"FYI255","expirationTime":"2022-05-23T12:18:46+01:00","name":"DHL","locale":"de_DE"}
+Example response
+HTTP/1.1 200 OK
+Content-Type: application/json
+Content-Length: 104
+
+{"id":3,"name":"DHL","reference":"FYI255","locale":"de_DE","expirationTime":"2022-05-23T12:18:46+01:00"}
+CURL request
+$ curl 'http://localhost:8080/partner/3' -i -X PUT \
+ -H 'Content-Type: application/json' \
+ -d '{"reference":"FYI255","expirationTime":"2022-05-23T12:18:46+01:00","name":"DHL","locale":"de_DE"}'
+Example PUT request with errors
+The errors for validating locale and date are the same between PUT and POST
+Example with error on update with not unique reference
+$ curl --location --request PUT 'http://localhost:8080/partner/1' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "name": "UPS",
+ "reference": "FYI5",
+ "locale": "en_US",
+ "expirationTime": "2022-05-23T12:18:46-05:00"
+}'
+Response
+{
+ "code": 500,
+ "message": "could not execute statement; SQL [n/a]; constraint [\"PUBLIC.CONSTRAINT_INDEX_7 ON PUBLIC.PARTNERS(REF) VALUES 5\"; SQL statement:\nupdate partners set expires=?, locale=?, company_name=?, ref=? where id=? [23505-200]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
+}
+
+ Note
+ |
++The reference attribute is configured to be a unique identifier for the partner + | +
Example with error on update with partner not found
+$ curl --location --request PUT 'http://localhost:8080/partner/4000' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "name": "UPS",
+ "reference": "FYI50",
+ "locale": "en_US",
+ "expirationTime": "2022-05-23T12:18:46-05:00"
+}'
+Response
+{
+ "code": 404,
+ "message": "Partner with id 4000 not found!"
+}
+Accessing the partner DELETE endpoint
+A DELETE
request is used to delete the partner.
Request structure
+DELETE /partner/2 HTTP/1.1
+Host: localhost:8080
+Path Parameters
+Parameter | +Description | +
---|---|
|
+The id of the partner to delete |
+
Example response
+HTTP/1.1 200 OK
+CURL request
+$ curl 'http://localhost:8080/partner/2' -i -X DELETE
+Example DELETE request with errors
+Example with error on update with with partner not found
+$ curl --location --request DELETE 'http://localhost:8080/partner/2000'
+Response
+{
+ "code": 404,
+ "message": "Partner with id 2000 not found!"
+}
+Useful commands
+Assuming you are using a bash cli
+Run the app in dev env
+./gradlew bootRun+
Run the test suite with gradle
+./gradlew test+
Prepare the jar archive with gradle for deployment
+./gradlew clean bootJar+
+ Note
+ |
+
+Path of the output is build/libs/api-spring-gradle-b2boost-0.0.1-SNAPSHOT.jar
+ |
+