Vavr Hands-on Lab
This repository contains a simple project that is refactored using Vavr.
The master
branch contains the unrefactored code.
The stepN-TOPIC
branches each introduces a Vavr concept into the
refactored master
branch.
- Note 1:
stepN
includes the refactorings ofstep1
tostepN-1
. - Note 2: you need to use a Lombok plugin in your IDE
Topics
- Using
Option
- Introducing Vavr Collections and interoperability
- Introducing Vavr-Jackson, Vavr at your boundary
- Functional exception handling using
Lift
- Functional exception handling using
Try
- Functional exception handling using
Either
- Using Vavr Streams with exceptions
- Property testing the REST interface
Application overview
The application in question is a simple microservice, that exposes Teams via REST-CRUD interface.
Start the application by running
$ ./gradlew bootRun
Fetching teams
Then fetch the teams using for example HTTPie:
$ http localhost:8080/teams
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Date: Mon, 25 Sep 2017 09:25:40 GMT
Transfer-Encoding: chunked
[
{
"foundedOn": [
1895,
5,
5
],
"id": "1",
"logoUrl": "https://tmssl.akamaized.net//images/wappen/head/38.png?lm=1405514004",
"name": "Fortuna Düsseldorf"
},
...
A single team is fetched using
$ http localhost:8080/teams/1
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Date: Mon, 25 Sep 2017 09:27:12 GMT
Transfer-Encoding: chunked
{
"coach": "Friedhelm Funkel",
"estimatedMarketValue": 13000000,
"foundedOn": [
1895,
5,
5
],
"id": "1",
"logoUrl": "https://tmssl.akamaized.net//images/wappen/head/38.png?lm=1405514004",
"name": "Fortuna Düsseldorf"
}
Using jq you can select for example the team names
$ http localhost:8080/teams | jq '.[].name'
"Fortuna Düsseldorf"
"1. FC Kaiserslautern"
"FC St Pauli"
"Eintracht Braunschweig"
or the logo URLs, which contain invalid entries:
$ http localhost:8080/teams | jq '.[].logoUrl'
"https://tmssl.akamaized.net//images/wappen/head/38.png?lm=1405514004"
"This is not a valid url"
"https://this.will.point.nowhere.de/"
"http://localhost:8080/timeout"
Fetching logos
The logo is exposed as a sub-resource (Base64 encoded)
$ http localhost:8080/teams/1/logo
HTTP/1.1 200
Content-Type: application/json
Date: Mon, 25 Sep 2017 18:55:39 GMT
Transfer-Encoding: chunked
+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+
If you want the actual logo as a picture, just store it like this
$ http localhost:8080/teams/1/logo > ~/tmp/out.png
You will notice, that some teams feature invalid URLs as their logo This will result in a timeout:
$ http localhost:8080/teams/3/logo
HTTP/1.1 400
Connection: close
Content-Length: 0
Date: Mon, 25 Sep 2017 18:57:56 GMT
This is expected and used to demo, how exceptions can be handled.
About timeout
If you try to access the logo of team number 4, then you will run into a timeout.
$ http localhost:8080/teams/4/logo
HTTP/1.1 408
Connection: close
Content-Length: 0
Date: Mon, 25 Sep 2017 18:56:54 GMT
This is expected and used to demo, how time outs can be handled.
The Kata
- Preparation
- Checkout the master branch and build the project
$ ./gradlew build
- Import the project into your IDE of choice
-
Using collections
-
Avoiding null with option
-
Use Vavr in your REST interfaces
-
Errorhandling with try
-
Property based testing for the controller