-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 20ac86e
Showing
93 changed files
with
1,971 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: publish-openapi | ||
on: | ||
push: | ||
branches: | ||
- main | ||
jobs: | ||
publish: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2.4.0 | ||
- name: Setup Scala | ||
uses: olafurpg/setup-scala@v13 | ||
with: | ||
java-version: openjdk@1.11.0 | ||
- name: Generate OpenApi Spec | ||
working-directory: tapir-akka-http | ||
run: sbt "runMain com.test.example.http_example.OpenApiGenerator $GITHUB_WORKSPACE/openapi.yaml" | ||
- name: Swagger ui action | ||
id: swagger-ui-action | ||
uses: pjoc-team/swagger-ui-action@v0.0.2 | ||
with: | ||
dir: ./ | ||
pattern: openapi.yaml | ||
- name: Deploy | ||
uses: peaceiris/actions-gh-pages@v3 | ||
with: | ||
github_token: ${{ secrets.GITHUB_TOKEN }} | ||
publish_branch: gh-pages | ||
publish_dir: swagger-ui |
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,4 @@ | ||
**/.bsp/ | ||
**/*.iml | ||
**/.idea | ||
**/target/ |
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,97 @@ | ||
# HTTP Framework Samples in Scala | ||
|
||
# Design | ||
|
||
All implementations follows below design: | ||
|
||
<br><br><br><br> | ||
![Floe diagram](images/flow-diagram.png) | ||
<br><br><br><br> | ||
|
||
# Rest implementation: ☕️ Coffee Shop API | ||
|
||
All examples are using [coffee-shop](https://github.com/veysiertekin/coffee-shop) static rest service except ZIO Http because of the some bugs. For ZIO, I have implemented a simple [Heroku service described here](https://github.com/veysiertekin/scala-http-framework-samples#simple-remote-service-on-heroku). | ||
|
||
|
||
|Endpoint|Description|Return type|Request example|Return example| | ||
|---|---|---|---|---| | ||
|/coffee|Returns coffee types|<pre>Array[String]</pre>|http://localhost:9000/coffee|<pre>[<br> "hots",<br> "iced" <br>]</pre>| | ||
|/coffee/#category|Drinks in the category|<pre>Array[<br> Drink(<br> title: String,<br> id: Int,<br> description: String,<br> ingredients: List[String]<br> )<br>]</pre>|http://localhost:9000/coffee/hots|<pre>[<br> {<br> "title": "Black",<br> "id": 1,<br> "description": "Black coffee is as simple as it gets with ground coffee beans steeped in hot water, served warm. And if you want to sound fancy, you can call black coffee by its proper name: cafe noir.",<br> "ingredients": [<br> "Coffee"<br> ]<br> },<br>...</pre>| | ||
|
||
|
||
## Akka Http | ||
|
||
* Functional implementation | ||
* [Native Datadog support](https://docs.datadoghq.com/tracing/setup_overview/compatibility_requirements/java/#web-framework-compatibility) | ||
* Supports full HTTP protocol | ||
* Detailed documentation: [https://doc.akka.io/docs/akka-http/current/index.html](https://doc.akka.io/docs/akka-http/current/index.html) | ||
|
||
## Http4s | ||
|
||
* Functional implementation | ||
* Support for effect libraries (cats effect etc) | ||
* Limited Datadog support via third party libraries ( [avast/datadog4s](https://github.com/avast/datadog4s), [Kamon](https://github.com/kamon-io/Kamon) etc). Integration in progress: [https://github.com/DataDog/dd-trace-java/issues/1934](https://github.com/DataDog/dd-trace-java/issues/1934) | ||
* Supports full HTTP protocol | ||
* Limited documentation: [https://http4s.org/v0.23/index.html](https://http4s.org/v0.23/index.html) | ||
|
||
## ZIO Http | ||
|
||
(as of writing this documentation) | ||
|
||
* Does not support full Http Protocal | ||
* No native Datadog support yet | ||
* Client has major pitfalls: stable channel does not have Https support. Beta channel has some bugs (removes trailing `/` in the URLS etc) | ||
* Functional, and follows effect library guides | ||
* Limited documentation (explains just a simple example): [https://dream11.github.io/zio-http/docs/index](https://dream11.github.io/zio-http/docs/index) | ||
|
||
|
||
## Finatra | ||
|
||
* Play like dependency framework (Guice) support by default | ||
* Supports full HTTP protocol | ||
* Supports both Twitter's Future or Cats effect for processing | ||
* [Native Datadog support](https://docs.datadoghq.com/tracing/setup_overview/compatibility_requirements/java/#web-framework-compatibility) | ||
* Detailed documentation: [https://twitter.github.io/finatra/user-guide/](https://twitter.github.io/finatra/user-guide/) | ||
|
||
# OpenAPI Endpoint | ||
|
||
All tapir implementations exposes documentation automatically on API level. | ||
|
||
ReadDoc Web UI: [http://localhost:9000/docs](http://localhost:9000/docs) | ||
|
||
![Web UI](images/docs-ss.png) | ||
|
||
Additionally, `tapir-akka-http` also implements a way of exporting openapi yaml. A Github Action uses this implementation and publishes a static swagger documentation at [http://veysiertekin.github.io/scala-http-framework-samples](http://veysiertekin.github.io/scala-http-framework-samples) | ||
|
||
![Swagger UI](images/swagger-ui.png) | ||
|
||
# Simple Remote Service on Heroku | ||
|
||
(This Heroku service has been used in ZIO Http) | ||
|
||
1- Go to [heroku-coffee-shop-service/](heroku-coffee-shop-service) in your terminal. | ||
|
||
2- Login to Heroku: | ||
|
||
```bash | ||
heroku login | ||
``` | ||
|
||
3- Create a simple app | ||
|
||
```bash | ||
heroku create | ||
git push heroku main | ||
``` | ||
|
||
4- Start application by scaling it to `1` | ||
|
||
```bash | ||
heroku ps:scale web=1 | ||
``` | ||
|
||
4- You can view http location of the service by: | ||
|
||
```bash | ||
heroku open | ||
``` |
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 @@ | ||
web: npm start |
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,7 @@ | ||
{ | ||
"name": "Coffee Shop Service", | ||
"description": "static coffe-shop api", | ||
"repository": "https://github.com/veysiertekin/scala-http-framework-samples", | ||
"logo": "https://cdn.rawgit.com/heroku/node-js-getting-started/main/public/node.svg", | ||
"keywords": ["api","heroku"] | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "node-js-getting-started", | ||
"version": "0.3.0", | ||
"description": "A sample Node.js app using Express 4", | ||
"engines": { | ||
"node": "14.x" | ||
}, | ||
"main": "index.js", | ||
"scripts": { | ||
"start": "node index.js", | ||
"test": "node test.js" | ||
}, | ||
"dependencies": { | ||
"ejs": "^3.1.5", | ||
"express": "^4.15.2" | ||
}, | ||
"devDependencies": { | ||
"got": "^11.3.0", | ||
"tape": "^4.7.0" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/heroku/node-js-getting-started" | ||
}, | ||
"keywords": [ | ||
"node", | ||
"heroku", | ||
"express" | ||
], | ||
"license": "MIT" | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,3 @@ | ||
*.class | ||
.idea | ||
target/ |
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,18 @@ | ||
lazy val akkaHttpVersion = "10.2.7" | ||
lazy val akkaVersion = "2.6.17" | ||
|
||
lazy val root = (project in file(".")). | ||
settings( | ||
inThisBuild(List( | ||
organization := "com.test.http_example", | ||
scalaVersion := "2.13.4" | ||
)), | ||
name := "akka-http", | ||
libraryDependencies ++= Seq( | ||
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion, | ||
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion, | ||
"com.typesafe.akka" %% "akka-actor-typed" % akkaVersion, | ||
"com.typesafe.akka" %% "akka-stream" % akkaVersion, | ||
"ch.qos.logback" % "logback-classic" % "1.2.3" | ||
) | ||
) |
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 @@ | ||
sbt.version=1.4.6 |
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 @@ | ||
addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") |
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,5 @@ | ||
sample-http-app { | ||
routes { | ||
ask-timeout = 5s | ||
} | ||
} |
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,18 @@ | ||
<configuration> | ||
<appender name="STDOUT" target="System.out" class="ch.qos.logback.core.ConsoleAppender"> | ||
<encoder> | ||
<pattern>[%date{ISO8601}] [%level] [%logger] [%thread] [%X{akkaSource}] - %msg%n</pattern> | ||
</encoder> | ||
</appender> | ||
|
||
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> | ||
<queueSize>1024</queueSize> | ||
<neverBlock>true</neverBlock> | ||
<appender-ref ref="STDOUT"/> | ||
</appender> | ||
|
||
<root level="INFO"> | ||
<appender-ref ref="ASYNC"/> | ||
</root> | ||
|
||
</configuration> |
43 changes: 43 additions & 0 deletions
43
std-akka-http/src/main/scala/com/test/example/akkahttp/App.scala
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,43 @@ | ||
package com.test.example.akkahttp | ||
|
||
import akka.actor.CoordinatedShutdown | ||
import akka.actor.typed.ActorSystem | ||
import akka.actor.typed.scaladsl.Behaviors | ||
import akka.http.scaladsl.Http | ||
import akka.http.scaladsl.server.Route | ||
import scala.util.{Failure, Success} | ||
|
||
object App { | ||
case object UserInitiatedShutdown extends CoordinatedShutdown.Reason | ||
|
||
private def startHttpServer(routes: Route)(implicit system: ActorSystem[_]): Unit = { | ||
import system.executionContext | ||
|
||
val futureBinding = Http() | ||
.newServerAt("0.0.0.0", 9000) | ||
.bind(routes) | ||
|
||
futureBinding.onComplete { | ||
case Success(binding) => | ||
val address = binding.localAddress | ||
system.log.info("Server online at http://{}:{}/", address.getHostString, address.getPort) | ||
case Failure(ex) => | ||
system.log.error("Failed to bind HTTP endpoint, terminating system", ex) | ||
system.terminate() | ||
} | ||
} | ||
|
||
def main(args: Array[String]): Unit = { | ||
val rootBehavior = Behaviors.setup[Nothing] { context => | ||
val coffeeShopActor = context.spawn(CoffeeShopActor(), "CoffeeShopActor") | ||
context.watch(coffeeShopActor) | ||
|
||
val routes = new CoffeeRoutes(coffeeShopActor)(context.system) | ||
startHttpServer(routes.routes)(context.system) | ||
Behaviors.empty | ||
} | ||
|
||
val system = ActorSystem[Nothing](rootBehavior, "SampleServer") | ||
//CoordinatedShutdown(system).run(UserInitiatedShutdown) | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
std-akka-http/src/main/scala/com/test/example/akkahttp/CoffeeRoutes.scala
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,38 @@ | ||
package com.test.example.akkahttp | ||
|
||
import akka.actor.typed.scaladsl.AskPattern._ | ||
import akka.actor.typed.{ActorRef, ActorSystem} | ||
import akka.http.scaladsl.model.StatusCodes | ||
import akka.http.scaladsl.server.Directives._ | ||
import akka.http.scaladsl.server.Route | ||
import akka.util.Timeout | ||
import com.test.example.akkahttp.CoffeeShopActor._ | ||
import scala.concurrent.Future | ||
|
||
class CoffeeRoutes(actor: ActorRef[CoffeeShopActor.Command])(implicit val system: ActorSystem[_]) extends JsonSupport { | ||
private implicit val timeout: Timeout = Timeout.create(system.settings.config.getDuration("sample-http-app.routes.ask-timeout")) | ||
|
||
def getTypes: Future[Array[String]] = actor askWithStatus GetTypes | ||
|
||
def getDrinks(coffeeType: String): Future[Array[Drink]] = actor askWithStatus { replyTo => | ||
GetDrinks(coffeeType, replyTo) | ||
} | ||
|
||
val routes: Route = | ||
pathPrefix("coffee") { | ||
concat( | ||
pathEnd { | ||
get { | ||
onSuccess(getTypes) { types => | ||
complete(StatusCodes.OK, types) | ||
} | ||
} | ||
}, | ||
path(Segment) { coffeeType => | ||
onSuccess(getDrinks(coffeeType)) { types => | ||
complete(StatusCodes.OK, types) | ||
} | ||
} | ||
) | ||
} | ||
} |
Oops, something went wrong.