• Stars
    star
    114
  • Rank 308,031 (Top 7 %)
  • Language
    Scala
  • License
    Apache License 2.0
  • Created over 9 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A study project how akka-http works

akka-http-test

Join the chat at https://gitter.im/dnvriend/akka-http-test Build Status License

A study project how akka-http works. The code below is a bit compacted, so please use it for reference only how the (new) API must be used. It will not compile/work correctly when you just copy/paste it. Check out the working source code for correct usage.

Mastering Akka by Chris Baxter

A great book ETA October 2016 by Packt Publishing, written by Chris Baxter and reviewed by me is Mastering Akka which will contain everything you ever wanted to know about akka-actors, akka-persistence, akka-streams, akka-http and akka-cluster, ConductR, Domain Driven Design and Event Sourcing. Its a book you just should have.

Contribution policy

Contributions via GitHub pull requests are gladly accepted from their original author. Along with any pull requests, please state that the contribution is your original work and that you license the work to the project under the project's open source license. Whether or not you state this explicitly, by submitting any copyrighted material via pull request, email, or other means you agree to license the material under the project's open source license and warrant that you have the legal authority to do so.

License

This code is open source software licensed under the Apache 2.0 License.

akka http documentation

Akka http now has its own release scheme and is not tied to that of akka anymore. As such, you should update your build file accordingly.

Source Streaming

As of Akka v2.4.9-RC1, akka-http supports completing a request with an Akka Source[T, _], which makes it possible to easily build and consume streaming end-to-end APIs which apply back-pressure throughout the entire stack!

Web Service Clients (RPC)

Akka-Http has a client API and as such RPC's can be created. Take a look at the package com.github.dnvriend.webservices, I have created some example RPC style web service clients for eetnu, iens, postcode, openWeatherApi, based on the generic com.github.dnvriend.webservices.generic.HttpClient client that supports Http and SSL connections with basic authentication or one legged OAuth1 with consumerKey and consumerSecret configuration from application.conf. The RPC clients also support for single RPC without cached connections and the streaming cached connection style where you can stream data to your clients. For usage please see the tests for the RPC clients. Good stuff :)

Web Server

A new HTTP server can be launched using the Http() class. The bindAndHandle() method is a convenience method which starts a new HTTP server at the given endpoint and uses the given 'handler' Flow for processing all incoming connections.

The number of concurrently accepted connections can be configured by overriding akka.http.server.max-connections setting.

import akka.http.scaladsl._
import akka.http.scaladsl.model._
import akka.stream.scaladsl._

def routes: Flow[HttpRequest, HttpResponse, Unit]

Http().bindAndHandle(routes, "0.0.0.0", 8080)

Routes

First some Akka Stream parley:

  • Stream: a continually moving flow of elements,
  • Element: the processing unit of streams,
  • Processing stage: building blocks that build up a Flow or FlowGraph for example map(), filter(), transform(), junction() etc,
  • Source: a processing stage with exactly one output, emitting data elements when downstream processing stages are ready to receive them,
  • Sink: a processing stage with exactly one input, requesting and accepting data elements
  • Flow: a processing stage with exactly one input and output, which connects its up- and downstream by moving/transforming the data elements flowing through it,
  • Runnable flow: A flow that has both ends attached to a Source and Sink respectively,
  • Materialized flow: An instantiation / incarnation / materialization of the abstract processing-flow template.

The abstractions above (Flow, Source, Sink, Processing stage) are used to create a processing-stream template or blueprint. When the template has a Source connected to a Sink with optionally some processing stages between them, such a template is called a Runnable Flow.

The materializer for akka-stream is the ActorMaterializer which takes the list of transformations comprising a akka.stream.scaladsl.Flow and materializes them in the form of org.reactivestreams.Processor instances, in which every stage is converted into one actor.

In akka-http parley, a 'Route' is a Flow[HttpRequest, HttpResponse, Unit] so it is a processing stage that transforms HttpRequest elements to HttpResponse elements.

Streams everywhere

The following reactive-streams are defined in akka-http:

  • Requests on one HTTP connection,
  • Responses on one HTTP connection,
  • Chunks of a chunked message,
  • Bytes of a message entity.

Route Directives

Akka http uses the route directives we know (and love) from Spray:

import akka.http.scaladsl._
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.stream.scaladsl._

def routes: Flow[HttpRequest, HttpResponse, Unit] =
  logRequestResult("akka-http-test") {
    path("") {
      redirect("person", StatusCodes.PermanentRedirect)
    } ~
    pathPrefix("person") {
      complete {
        Person("John Doe", 25)
      }
    } ~
    pathPrefix("ping") {
      complete {
        Ping(TimeUtil.timestamp)
      }
    }
  }

Spray-Json

I'm glad to see that akka-http-spray-json-experimental basically has the same API as spray:

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.RequestEntity
import akka.http.scaladsl.unmarshalling.Unmarshal
import spray.json.DefaultJsonProtocol._
import spray.json._

case class Person(name: String, age: Int)

val personJson = """{"name":"John Doe","age":25}"""

implicit val personJsonFormat = jsonFormat2(Person)

Person("John Doe", 25).toJson.compactPrint shouldBe personJson

personJson.parseJson.convertTo[Person] shouldBe Person("John Doe", 25)

val person = Person("John Doe", 25)
val entity = Marshal(person).to[RequestEntity].futureValue
Unmarshal(entity).to[Person].futureValue shouldBe person

Custom Marshalling/Unmarshalling

Akka http has a cleaner API for custom types compared to Spray's. Out of the box it has support to marshal to/from basic types (Byte/String/NodeSeq) and so we can marshal/unmarshal from/to case classes from any line format. The API uses the Marshal object to do the marshalling and the Unmarshal object to to the unmarshal process. Both interfaces return Futures that contain the outcome.

The Unmarshal class uses an Unmarshaller that defines how an encoding like eg XML can be converted from eg. a NodeSeq to a custom type, like eg. a Person.

To Marshal class uses Marshallers to do the heavy lifting. There are three kinds of marshallers, they all do the same, but one is not interested in the MediaType , the opaque marshaller, then there is the withOpenCharset marshaller, that is only interested in the mediatype, and forwards the received HttpCharset to the marshal function so that the responsibility for handling the character encoding is up to the developer, and the last one, the withFixedCharset will handle only HttpCharsets that match the marshaller configured one.

An example XML marshaller/unmarshaller:

import akka.http.scaladsl.marshalling.{ Marshal, Marshaller, Marshalling }
import akka.http.scaladsl.model.HttpCharset
import akka.http.scaladsl.model.HttpCharsets._
import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.unmarshalling.{ Unmarshal, Unmarshaller }

import scala.xml.NodeSeq

case class Person(name: String, age: Int)

val personXml =
  <person>
    <name>John Doe</name>
    <age>25</age>
  </person>

implicit val personUnmarshaller = Unmarshaller.strict[NodeSeq, Person] { xml ⇒
  Person((xml \\ "name").text, (xml \\ "age").text.toInt)
}

val opaquePersonMarshalling = Marshalling.Opaque(() ⇒ personXml)
val openCharsetPersonMarshalling = Marshalling.WithOpenCharset(`text/xml`, (charset: HttpCharset) ⇒ personXml)
val fixedCharsetPersonMarshalling = Marshalling.WithFixedCharset(`text/xml`, `UTF-8`, () ⇒ personXml)

val opaquePersonMarshaller = Marshaller.opaque[Person, NodeSeq] { person ⇒ personXml }
val withFixedCharsetPersonMarshaller = Marshaller.withFixedCharset[Person, NodeSeq](`text/xml`, `UTF-8`) { person ⇒ personXml }
val withOpenCharsetCharsetPersonMarshaller = Marshaller.withOpenCharset[Person, NodeSeq](`text/xml`) { (person, charset) ⇒ personXml }

implicit val personMarshaller = Marshaller.oneOf[Person, NodeSeq](opaquePersonMarshaller, withFixedCharsetPersonMarshaller, withOpenCharsetCharsetPersonMarshaller)

"personXml" should "be unmarshalled" in {
  Unmarshal(personXml).to[Person].futureValue shouldBe Person("John Doe", 25)
}

"Person" should "be marshalled" in {
  Marshal(Person("John Doe", 25)).to[NodeSeq].futureValue shouldBe personXml
}

Vendor specific media types

Versioning an API can be tricky. The key is choosing a strategy on how to do versioning. I have found and tried the following stragegies as blogged by Jim Liddell's blog, which is great by the way!

  1. 'The URL is king' in which the URL is encoded in the URL eg. http://localhost:8080/api/v1/person. The downside of this strategy is that the location of a resource may not change, and when we request another representation, the url does change eg. to http://localhost:8080/api/v2/person.
  2. Using a version request parameter like: http://localhost:8080/api/person?version=1. The downside of this stragegy lies in the fact that resource urls must be as lean as possible, and the only exception is for filtering, sorting, searching and paging, as stated by Vinay Sahni in his great blog 'Best Practices for Designing a Pragmatic RESTful API'.
  3. Both bloggers and I agree that using request headers for versioning, and therefor relying on vendor specific media types is a great way to keep the resource urls clean, the location does not change and in code the versioning is only a presentation responsibility, easilly resolved by an in scope mashaller.

When you run the example, you can try the following requests:

# The latest version in JSON
curl -H "Accept: application/json" localhost:8080/person
http :8080/person
# A stream of persons in CSV
curl -H "Accept: text/csv" localhost:8080/persons/stream/100
http :8080/persons/stream/100 Accept:text/csv
# A stream of persons in JSON
curl -H "Accept: application/json" localhost:8080/persons/stream/100
http :8080/persons/stream/100 Accept:application/json
# A list of of persons in JSON
curl -H "Accept: application/json" localhost:8080/persons/strict/100
http :8080/persons/strict/100 Accept:application/json
# The latest version in XML
curl -H "Accept: application/xml" localhost:8080/person
http :8080/person Accept:application/xml
# Vendor specific header for JSON v1
curl -H "Accept: application/vnd.acme.v1+json" localhost:8080/person
http :8080/person Accept:application/vnd.acme.v1+json
# Vendor specific header for JSON v2
curl -H "Accept: application/vnd.acme.v2+json" localhost:8080/person
http :8080/person Accept:application/vnd.acme.v2+json
# Vendor specific header for XML v1
curl -H "Accept: application/vnd.acme.v1+xml" localhost:8080/person
http :8080/person Accept:application/vnd.acme.v2+json
# Vendor specific header for XML v2
curl -H "Accept: application/vnd.acme.v2+xml" localhost:8080/person
http :8080/person Accept:application/vnd.acme.v2+xml

Please take a look at the Marshallers trait for an example how you could implement this strategy and the MarshallersTest how to test the routes using the Accept header and leveraging the media types.

Video

Slides

Northeast Scala Symposium 2015

Projects that use akka-http

More Repositories

1

akka-persistence-inmemory

Akka-persistence-inmemory is a plugin for akka-persistence that stores journal and snapshot messages memory, which is very useful when testing persistent actors, persistent FSM and akka cluster
Scala
134
star
2

intro-to-akka-streams

Scala
69
star
3

akka-concurrency-test

Study on what Threads, ThreadPools, Executors, ExecutorServices, ExecutionContext, Futures are and how to configure them
Scala
69
star
4

reactive-programming

Principles of Reactive Programming
Scala
60
star
5

sbt-sam

Plugin and library to create enterprise-cloud applications leveraging SBT and the SAM component model
Scala
34
star
6

akka-serialization-test

Study on akka-serialization using ProtoBuf, Kryo and Avro
Scala
31
star
7

demo-akka-persistence-jdbc

A small akka-persistence-jdbc demo project
Scala
18
star
8

docker-timezone-test

How to work with timezones with Scala and Docker and how to process messages that have a timezone embedded
Scala
13
star
9

design-patterns-study

a study into object oriented and functional design patterns
Scala
12
star
10

reactive-activemq

An akka-streams implementation to consume and produce messages from ActiveMq queues and topics.
Scala
11
star
11

lagom-test

A small study project on lagom-scala
Scala
11
star
12

jboss-wildfly-test

study project into Wildfly using docker, including how to configure the server, data sources, jms and users
Scala
10
star
13

reactive-frameworks

A small study project on the capabilities of reactive frameworks
Scala
10
star
14

akka-persistence-jounal-writer

Write events directly to an akka-persistence journal bypassing persistent-actor lifecycle overhead
Scala
9
star
15

kafka-streams-scala

A fluent Scala API for kafka-streams
Scala
7
star
16

spark-scala

Basic wrapper for the great SparkJava project
Java
7
star
17

type-classes-example

A small study project on type classes, level of entry is 'beginner'
Scala
7
star
18

akka-elasticsearch

An ElasticSearch extension for Akka
Scala
7
star
19

aws-rds-to-google-cloud-sql

A small study project on migrating databases from AWS to GCP
7
star
20

study-distributed-computing

A smal study project on distributed computing
Scala
6
star
21

sbt-plugin-seed.g8

A sbt-plugin seed template project
Scala
6
star
22

akka-persistence-query-extensions

non-official akka-persistence-query-extensions contain components that are very handy to have for using akka-stream, akka persistence and akka query
Scala
5
star
23

slick3-test

Study into Slick3 and Reactive Slick (reactive-streams) and interoperability with RxScala/RxJava using the adapter library
Scala
5
star
24

study-sbt

A quick study on sbt the Scala Build Tool
Scala
5
star
25

scala-jdbc

A small library that makes working with JDBC databases a whole lot easier.
Scala
5
star
26

docker-networking-test

docker network study that has been added to docker v1.9
Shell
4
star
27

akka-avro-serialization-test

A small study project how to serialize with apache Avro and akka-persistence using a single serializer
Scala
4
star
28

jdbc-scala

Quick view at the three JDBC database access libraries for Scala I like, spring-scala, ScalikeJdbc and Slick
Shell
4
star
29

sam-mini-platform

A mini platform for ingesting, processing, and analyzing data.
Scala
4
star
30

akka-persistence-fsm

How to persist FSM and how to shard them in a cluster
Scala
3
star
31

intellij-tips

A small study project on how to use IntelliJ effectively.
Scala
3
star
32

akka-camel-ping-pong

Example using Akka-Camel, ActiveMQ and Actors sending each other Ping/Pong messages
Scala
3
star
33

akka-stream-extensions

non-official extension library for akka-stream that contains operations like zipWithIndex, Source.fromTry and so on
Scala
3
star
34

akka-fuse-test

How to get Akka to work on JBoss Fuse
Scala
2
star
35

sam-seed.g8

An sbt-sam template for creating public accessible, stateless applications
Scala
2
star
36

macwire-test

A small study project on macwire a lightweight and nonintrusive Scala Dependency Injection library
Scala
2
star
37

slick-3.2.0-test

A small test project for slick 3.2.0 Milestone and Release Candidate releases
Scala
2
star
38

brew-documentation

2
star
39

akka-stream-xml-test

Study on xml processing with akka streams
Scala
2
star
40

akka-persistence-jdbc-play

An example play project using akka-persistence-jdbc
Scala
2
star
41

docker-logging-logstash-test

test how to link syslog messages of docker containers to logstash and ultimately to elasticsearch for exploration and visualization
Shell
1
star
42

cinnamon-slf4j-mdc-test

A small study project on lightbend cinnamon and slf4j MDC for futures and actors
Scala
1
star
43

sam-schema-repo-seed.g8

A template project for quickly creating a serverless avro schema repository
Scala
1
star
44

airflow-test

A small study project on apache airflow
1
star
45

demo-akka-persistence-inmemory

A small demo project for akka-persistence-inmemory
Scala
1
star
46

aws-meetup-2018-05-07-lambda-fargate-shake-that-shit

The demo project for Amsterdam AWS Meetup 2018-05-07 - lambda-fargate-shake-that-shit
Scala
1
star
47

kafka-test

small study project on Apache Kafka
Shell
1
star
48

sbt-native-packager-demo

A small study project on the sbt-native-packager
Scala
1
star
49

akka-http-crypto

A small study project on akka-http how to create a cryptographic service fast!
Scala
1
star
50

elasticsearch-cluster

Shell
1
star
51

akka-persistence-query-test

A small study project on the akka-persistence-query API as there is no TCK
Scala
1
star
52

terraform-test

A small study project on Terraform - Infrastructure as Code
HCL
1
star
53

my-scala-notes

my-scala-notes, because I've to put them somewhere
Scala
1
star
54

akka-persistence-jdbc-serialization-json

A JSON serializer for akka-persistence-jdbc
Scala
1
star
55

rabbitmq-akka-stream

Upgraded Activator template to study RabbitMQ and akka-streams
Scala
1
star
56

typescript-tutorial

A small study project on Typescript
TypeScript
1
star
57

conductr-test

A small study project on Lightbend Conductr
Scala
1
star
58

serverless-test

A small study project on the serverless-framework
Scala
1
star
59

apache-cassandra-test

A small study project on Apache Cassandra
Shell
1
star
60

akka-elasticsearch-logger

An ElasticSearch Logger for Akka, to be used with akka-elasticsearch
Scala
1
star
61

anorm-test

A small project on standalone-anorm.
Scala
1
star
62

shapeless-test

A small study project on shapeless
Scala
1
star
63

reactive-kafka-test

Scala
1
star
64

play-di-test

A small study project on how play's dependency injection works
Scala
1
star
65

sbt-parser-test

A small study project on sbt parser combinators
Scala
1
star
66

scalacheck-test

A small study project on scalacheck
Scala
1
star
67

sam-dynamodb-seed.g8

A template project for quickly creating stateful serverless applications using dynamodb.
Scala
1
star