14,99 €
This book is intended for the intermediate Scala programmer who is interested in functional programming and works mainly on the web service backend side. Ideally she has experience with libraries like Akka HTTP and Slick which are in heavy use in that area. However maybe you have wondered if we can't do better even though aforementioned projects are battle tested and proven. The answer to this can be found in this book which is intended to be read from cover to cover in the given order. Within the book the following libraries will be used: Cats, Cats Effect, http4s, Doobie, Refined, fs2, tapir, Monocle and probably others. ;-) This edition includes a chapter about migrating the project to Scala 3. Which includes all the nasty issues that we tend to run into if we touch code after a longer time. Code and book source can be found in the author's github account.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Veröffentlichungsjahr: 2021
Thank you for your interest in this book. I hope you’ll have a good time reading it and learn something from it.
This book is intended for the intermediate Scala programmer who is interested in functional programming and works mainly on the web service backend side. Ideally she has experience with libraries like Akka HTTP and Slick which are in heavy use in that area.
However maybe you have wondered if we can’t do better even though aforementioned projects are battle tested and proven.
The answer to this can be found in this book which is intended to be read from cover to cover in the given order. Within the book the following libraries will be used: Cats1, Cats Effect2, http4s3, Doobie4, Refined5, fs26, tapir7, Monocle8 and probably others. ;-)
This edition includes a chapter about migrating the project to Scala 3. Which includes all the nasty issues that we tend to run into if we touch code after a longer time.
Code and book source can be found in the following repository: https://github.com/jan0sch/pfhais
This book uses the Creative Commons Attribution ShareAlike 4.0 International (CC BY-SA 4.0) license9. The code snippets in this book are licensed under CC010 which means you can use them without restriction. Excerpts from libraries maintain their license.
Bear with me, this is obligatory under german law.
AutorJens Grassel: Wegtam GmbH, c/o J. Grassel, Neuer Markt 17, 18055 RostockUmschlaggestaltung, IllustrationJens GrasselISBN978-3-7521-4129-0https://typelevel.org/cats/↩︎
https://typelevel.org/cats-effect/↩︎
https://http4s.org/↩︎
https://tpolecat.github.io/doobie/↩︎
https://github.com/fthomas/refined↩︎
https://fs2.io/↩︎
https://github.com/softwaremill/tapir↩︎
https://github.com/julien-truffaut/Monocle↩︎
https://creativecommons.org/licenses/by-sa/4.0/legalcode↩︎
https://wiki.creativecommons.org/wiki/CC0↩︎
I would like to thank my beloved wife and family who bear with me and make all of this possible. Also I send a big thank you to all the nice people from the Scala community which I’ve had the pleasure to meet. Special thanks go to Adam Warski (tapir), Frank S. Thomas (refined), Julien Truffaut (Monocle) and Ross A. Baker (http4s) for their help, advise and patience.
For better understanding we will implement a small use case in both impure and pure way. The following section will outline the specification.
First we need to specify the exact scope and API of our service. We’ll design a service with a minimal API to keep things simple. It shall fulfil the following requirements.
The service shall provide HTTP API endpoints for:
the creation of a product data type identified by a unique idadding translations for a product name by language code and unique idreturning the existing translations for a productreturning a list of all existing products with their translationsWe will keep the model very simple to avoid going overboard with the implementation.
A language code shall be defined by the ISO 639-1 (e.g. a two letter code).A translation shall contain a language code and a product name (non-empty string).A product shall contain a unique id (UUID version 4) and a list of translations.The data will be stored in a relational database (RDBMS). Therefore we need to define the tables and relations within the database.
The table products must contain only the unique id which is also the primary key.
The table names must contain a column for the product id, one for the language code and one for the name. Its primary key is the combination of the product id and the language code. All columns must not be null. The relation to the products is realised by a foreign key constraint to the products table via the product id.
The HTTP API shall provide the following endpoints on the given paths:
PathHTTP methodFunction/productsPOSTCreate a product./productsGETGet all products and translations./product/{UUID}PUTAdd translations./product/{UUID}GETGet all translations for the product.The data shall be encoded in JSON using the following specification:
JSON for a translation
JSON for a product
This should be enough to get us started.
Within the Scala ecosystem the Akka-HTTP library is a popular choice for implementing server side backends for HTTP APIs. Another quite popular option is the Play framework but using a full blown web framework to just provide a thin API is overkill in most cases. As most services need a database the Slick library is another popular choice which completes the picture.
However while all mentioned libraries are battle tested and proven they still have problems.
If we want referential transparency, we must push the side effects to the boundaries of our system (program) which can be done by using lazy evaluation. Let’s repeat the previous example in a different way.
IO example 1
The above code will produce no output. Only if we evaluate the variable effect which is of type IO[Unit] will the output be generated (try effect.unsafeRunSync in the REPL). Also the second approach works like expected.
IO example 2
What have we gained?
Suddenly we can much more easily reason about our code! And why is that? Well we don’t have unexpected side effects caused by code running even when it doesn’t need to. This is a sneak peak how pure code looks like. Now we only need to implement pure libraries for our use, or do we?
Luckily for us meanwhile there are several pure options available in the Scala ecosystem. We will stick to the Cats family of libraries namely http4s and Doobie as replacements for Akka-HTTP and Slick. They build upon the Cats Effect library which is an implementation of an IO monad for Scala. Some other options exist but we’ll stick to the one from Cats.
To be able to contrast both ways of implementing a service we will first implement it using Akka-HTTP and Slick and will then migrate to http4s and Doobie.