Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added testing docs and some more separation
- Loading branch information
Showing
15 changed files
with
422 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
target/ | ||
.idea | ||
boot/ | ||
lib_managed/ | ||
src_managed/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
Backend Actor logic | ||
------------------- | ||
|
||
In this example, the backend only uses one basic actor. In a real system, we would have many actors interacting with each other and perhaps, multiple data stores and microservices. | ||
|
||
An interesting side-note to add here is perhaps about when using actors in applications like this adds value over just providing functions that would return Futures. | ||
In fact, if your logic is stateless and very simple request/reply style, you may not need to back it with an Actor. actors do shine however when you need to keep some form of state and allow various requests to access something in (or *through*) an Actor. The other stellar feature of actors, that futures would not handle, is scaling-out onto a cluster very easily, by using [Cluster Sharding](http://doc.akka.io/docs/akka/current/scala/cluster-sharding.html) or other [location-transparent](http://doc.akka.io/docs/akka/current/scala/general/remoting.html) techniques. | ||
|
||
However, the focus of this tutorial is on how to interact with an Actor backend from within Akka HTTP -- not on the actor itself, so we'll keep it very simple. | ||
|
||
The sample code in the `UserRegistryActor` is very simple. It keeps registered users in a `Set`. Once it receives messages it matches them to the defined cases to determine which action to take: | ||
|
||
@@snip [UserRegistryActor.scala]($g8src$/scala/com/lightbend/akka/http/sample/UserRegistryActor.scala) | ||
|
||
If you feel you need to brush up on your Akka Actor knowledge, the [Getting Started Guide]((http://doc.akka.io/docs/akka/current/scala/guide/index.html)) reviews actor concepts in the context of a simple Internet of Things (IoT) example. |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,40 @@ | ||
JSON conversion | ||
--------------- | ||
JSON marshalling | ||
---------------- | ||
|
||
When exercising the app, you interacted with JSON payloads. How does the example app convert data between JSON format and data that can be used by Scala classes? The answer begins in the server class definition `JsonSupport` trait: | ||
|
||
@@snip [QuickstartServer.scala]($g8src$/scala/com/lightbend/akka/http/sample/QuickstartServer.scala) { #main-class } | ||
@@snip [UserRoutes.scala]($g8src$/scala/com/lightbend/akka/http/sample/UserRoutes.scala) { #user-routes-class } | ||
|
||
This trait is implemented in the `JsonSupport.scala` source file: | ||
|
||
@@snip [JsonSupport.scala]($g8src$/scala/com/lightbend/akka/http/sample/JsonSupport.scala) | ||
|
||
We're using the [Spray JSON](https://github.com/spray/spray-json) library here, which allows us to define json marshallers | ||
(or `formats` how Spray JSON calls them) in a type-safe way. In other words, if we don't provide a format instance for | ||
a type, yet we'd try to return it in a route by calling `complete(someValue)` the code would not compile - saying that | ||
it does not know how to marshal the `SomeValue` type. This has the up-side of us being completely in control over what | ||
we want to expose, and not exposing some type accidentally in our API. | ||
|
||
To handle the two different payloads, the trait defines two implicit values; `userJsonFormat` and `usersJsonFormat`. Defining the formatters as `implicit` ensures that the compiler can map the formatting functionality with the case classes to convert. | ||
|
||
The `jsonFormatX` methods come from [Spray Json](https://github.com/spray/spray-json). The `X` represents the number of parameters in the underlying case classes: | ||
The `jsonFormatX` methods come from Spray JSON. The `X` represents the number of parameters in the underlying case classes: | ||
|
||
@@snip [UserRegistryActor.scala]($g8src$/scala/com/lightbend/akka/http/sample/UserRegistryActor.scala) { #user-case-classes } | ||
|
||
We won't go into how the formatters are implemented. All you need to remember for now is to define the formatters as implicit and that the formatter used should map the number of parameters belonging to the case class it converts. | ||
|
||
Comment: I was a bit confused by the previous paragraph. Does the user have to write their own formatters or are these available as libraries? | ||
We won't go into how the formatters are implemented - this is done for us by the library. All you need to remember for now is to define the formatters as implicit and that the formatter used should map the number of parameters belonging to the case class it converts. | ||
|
||
@@@ note | ||
|
||
While we used Spray JSON in this example, various other libraries are supported via the [Akka HTTP JSON](https://github.com/hseeberger/akka-http-json) | ||
project, including [Jackson](https://github.com/FasterXML/jackson), [Play JSON](https://www.playframework.com/documentation/2.6.x/ScalaJson) | ||
or [circe](https://circe.github.io/circe/). | ||
|
||
Each library comes with different trade-offs in performance and user-friendlieness. Spray JSON is generally the fastest, though it requires you to write the format | ||
values explicitly. If you'd rather make "everything" automatically marshallable into JSON values you might want to use Jackson or Circe instead. | ||
|
||
If you're not sure, we recommend sticking to Spray JSON as it's the closest in philosophy to Akka HTTP - being explicit about all capabilities. | ||
|
||
@@@ | ||
|
||
Now that we've examined the example app thoroughly, let's test a few the remaining use cases. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.