Pure functional HTTP APIs in Scala - Jens Grassel - E-Book

Pure functional HTTP APIs in Scala E-Book

Jens Grassel

0,0
14,99 €

oder
-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.
Mehr erfahren.
Beschreibung

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:

EPUB

Veröffentlichungsjahr: 2021

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Pure functional HTTP APIs in Scala

ForewordAbout this bookCopyleft NoticeThanksOur use caseService specificationData modelDatabaseThe products tableThe names tableHTTP APIThe state of the artProblemsMaybe there is another wayImpure implementationModelsDatabase layerMigrationsSlick tablesAkka-HTTP routesProblems with the solutionPure implementationPure configuration handlingModelsDatabase layerMigrationsDoobiehttp4s routesStreaming - Take 1Streaming - Take 2JSON troubleStarting the applicationWhat about tests?Testing the impure serviceGeneratorsUnit TestsIntegration TestsTesting the pure serviceUnit TestsIntegration TestsAdding benchmarksOur environmentSystem environmentComparisonCreate 100.000 productsLoad 100.000 productsUpdate 100.000 productsBulk load all 100.000 productsSummaryDocumenting your APIThe lay of the landUsing types to describe an APIA pure implementation using tapir.BasicsProduct routesProducts routesDocumentation via OpenAPIRefining the generated documentationMoving to Scala 3…Step 1: Updating to 2.13.xDetails and some compiling issuesStep 2: Migrating to Scala 3Epilogue

Foreword

Thank you for your interest in this book. I hope you’ll have a good time reading it and learn something from it.

About this book

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

Copyleft Notice

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.

Imprint / Impressum

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-0

https://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↩︎

Thanks

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.

Our use case

For better understanding we will implement a small use case in both impure and pure way. The following section will outline the specification.

Service 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 translations

Data model

We 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.

Database

The data will be stored in a relational database (RDBMS). Therefore we need to define the tables and relations within the database.

The products table

The table products must contain only the unique id which is also the primary key.

The names table

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.

HTTP API

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

{"lang":"ISO-639-1 Code","name":"A non empty string."}

JSON for a product

{"id":"The-UUID-of-the-product","names":[//Alistoftranslations.]}

This should be enough to get us started.

The state of the art

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.

Maybe there is another way

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

import cats.effect.IOimport cats.implicits._val effect for{ _ <-IO(println("Hi there!")) _ <-IO(println("Hi there!"))}yield()

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

import cats.effect.IOimport cats.implicits._val printF IO(println("Hi there!"))val effect for{ _ <- printF _ <- printF}yield()

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.

---ENDE DER LESEPROBE---