标签: akka-http

使用Akka HTTP创建基本HTTP Post请求的惯用法

我正在试图弄清楚如何使用Akka HTTP库创建基本的HTTP POST请求.这就是我想出的:

val formData = Await.result(Marshal(FormData(combinedParams)).to[RequestEntity], Duration.Inf)
val r = HttpRequest(POST, url, headers, formData)
Run Code Online (Sandbox Code Playgroud)

问题是,对我来说,它似乎有点不合时宜.还有其他方法可以从FormData创建HttpEntity吗?特别是Await即使数据很容易获得,我必须使用或返回Future 的事实对于这样一个简单的任务来说似乎过于复杂.

scala akka akka-http

11
推荐指数
2
解决办法
9611
查看次数

具有多种路由配置的akka​​-http

快速背景

我正在通过一些示例来学习Akka HTTP堆栈以创建新的REST项目(完全非UI).我一直在使用和扩充Akka HTTP微服务示例来处理大量用例和配置,并对Scala和Akka HTTP的工作情况感到惊喜.

当前设置

目前我有这样的配置:

object AkkaHttpMicroservice extends App with Service {
  override implicit val system = ActorSystem()
  override implicit val executor = system.dispatcher
  override implicit val materializer = ActorMaterializer()

  override val config = ConfigFactory.load()
  override val logger = Logging(system, getClass)

  Http().bindAndHandle(routes, config.getString("http.interface"), config.getInt("http.port"))
}
Run Code Online (Sandbox Code Playgroud)

routes参数仅具有使用在其内的典型数据的简单值path,pathPrefix

问题

有没有办法在多个Scala文件或某个地方设置路由?

我真的希望能够定义一组类来分离关注点并处理Actor设置和处理以处理应用程序的不同区域,并将编组保留到根App扩展.

对于我如何使用像@javax.ws.rs.Path("/whatever")我的类这样的注释在Java中做事情,我可能会想太多.如果是这种情况,请随时指出思维方式的变化.

我试图寻找一些不同的组关键字,但相信我问错了问题(例如,1,2).

scala akka-http

11
推荐指数
1
解决办法
8935
查看次数

akka-stream + akka-http生命周期

TLDR:当我有一个传出的http请求作为流的一部分时,是否更好地为每个请求实现一个流(即使用短期流)或跨请求使用单个流实现?

详细信息:我有一个典型的服务,它接受HTTP请求,将其分散到多个第三方下游服务(不受我控制),并在发送回来之前聚合结果.我正在使用akka-http进行客户端实现并为服务器进行喷涂(遗留,随着时间推移将转移到akka-http).示意图:

request -> map -1-*-> map -> 3rd party http -> map -*-1> aggregation -> response

这可以通过为每个请求实现流或实现(部分)流一次并在请求之间共享来实现.

每个请求的实现产生实现开销1,并且不清楚如何利用连接池.这里描述这个问题(许多实现可能会耗尽池).我可以像这里一样长时间运行的http流中包装一个池并包装在mapAsync"上游"中,但错误处理策略对我来说并不清楚.当单个请求失败并且流终止时,它是否会取消池?此外,似乎我需要协调请求和响应,因为它们不会按顺序返回.

// example of stream per request

val connectionFlow = Http().cachedHostConnectionPool[UUID](host, port)
val httpFlow: Flow[HttpRequest, Try[HttpResponse], NotUsed] =
    Flow[HttpRequest]
      .map(req => req -> UUID.randomUUID()) // I don't care about id because it's a single request per stream.
      .via(connectionFlow)
      .map { case (response, _) => response }

val result = Range(1 …
Run Code Online (Sandbox Code Playgroud)

scala akka-stream akka-http

11
推荐指数
1
解决办法
445
查看次数

如何为akka http添加自定义marshaller?

作为scala和akka-http的初学者,我试图勾选序列化和编组过程.

该项目使用akka@2.5.2和akka-http@10.0.10".此外,它还包含akka-http-spray-json依赖项.

在代码库中,我们使用Java.Util.Currency(它可能已被弃用,这并不重要,因为我仍然想知道如何添加自定义编组器.)

鉴于此示例控制器:

def getCurrencyExample: Route = {
    path("currencyExample") {
      val currency: Currency = Currency.getInstance("EUR")
      val code: String = currency.getCurrencyCode

      val shouldBeFormated = collection.immutable.HashMap(
        "currencyCode" -> code,
        "currencyObject" -> currency
      )

      complete(shouldBeFormated)
    }
  }
Run Code Online (Sandbox Code Playgroud)

我得到这样的回复货币对象变空了:

 {
  currencyObject: { },
  currencyCode: "EUR",
 }
Run Code Online (Sandbox Code Playgroud)

我希望有类似的东西:

 {
  currencyObject: "EUR",
  currencyCode: "EUR",
 }
Run Code Online (Sandbox Code Playgroud)

currency对象应转换为JSON字符串.由于我不想手动转换每个响应,我想挂钩编组过程并在后台完成.

我想仅为Java.Util.Currency对象添加自定义marhaller ,但即使阅读文档,我也不确定如何继续.描述了多种方法,我不确定哪种方法符合我的需要,或者从哪里开始.


我尝试创建自己的CurrencyJsonProtocol:

package com.foo.api.marshallers

import java.util.Currency

import spray.json.{DefaultJsonProtocol, JsString, JsValue, RootJsonFormat}

object CurrencyJsonProtocol extends DefaultJsonProtocol { …
Run Code Online (Sandbox Code Playgroud)

json scala marshalling spray akka-http

11
推荐指数
1
解决办法
1222
查看次数

akka-http:如何设置响应头

我的路线如下:

val route = {
    logRequestResult("user-service") {
      pathPrefix("user") {
        get {
          respondWithHeader(RawHeader("Content-Type", "application/json")) {
            parameters("firstName".?, "lastName".?).as(Name) { name =>
              findUserByName(name) match {
                case Left(users) => complete(users)
                case Right(error) => complete(error)
              }
            }
          }
        } ~
          (put & entity(as[User])) { user =>
            complete(Created -> s"Hello ${user.firstName} ${user.lastName}")
          } ~
          (post & entity(as[User])) { user =>
            complete(s"Hello ${user.firstName} ${user.lastName}")
          } ~
          (delete & path(Segment)) { userId =>
            complete(s"Hello $userId")
          }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

我的回复的内容类型应始终application/json如我为get请求设置的那样.但是,我在测试中得到的是text/plain.如何在响应中正确设置内容类型?

另外,akka-http文档是我见过的最无价值的垃圾之一.几乎每个示例代码的链接都被破坏了,他们的解释只是说明了.Javadoc没有代码示例,我在Github上找不到他们的代码库,所以从他们的单元测试中学习也是不可能的.

scala routes akka spray akka-http

10
推荐指数
1
解决办法
6906
查看次数

如何在akka-http中读取查询参数?

我知道akka-http库在处理请求时编组和解组类类型.但是现在,我需要读取请求的请求参数GET.我尝试了parameter()方法,它返回ParamDefAux类型,但我需要这些值作为字符串类型

我在下面的问题中检查答案.

  1. 如何在喷涂路由中解析获取请求参数?

  2. 使用Akka HTTP查询GET请求的参数(正式名称为Spray)

但不能做我需要的.

请告诉我如何从请求中提取查询参数.或者如何从中提取所需的值ParamDefAux

请求网址

http://host:port/path?key=authType&value=Basic345
Run Code Online (Sandbox Code Playgroud)

获取方法定义

 val  propName = parameter("key")
 val  propValue = parameter("value")
 complete(persistanceMgr.deleteSetting(propName,propValue))
Run Code Online (Sandbox Code Playgroud)

我的方法声明

def deleteSetting(name:String,value:String): Future[String] = Future{
 code...
}
Run Code Online (Sandbox Code Playgroud)

scala akka-stream akka-http

10
推荐指数
1
解决办法
1万
查看次数

如何在Mashaller中使用http请求标头进行内容协商?

我的应用程序支持protobuf和JSON序列化.对于我使用的JSON序列化com.trueaccord.scalapb.json.JsonFormat,我的dtos是从proto定义生成的.

com.trueaccord串行包装选项类型,这是造成某些客户端的问题,所以我希望能够支持JSON对象org.json4s没有制动现有的客户.

我希望能够根据名为JFORMAT的自定义http头选择一个序列化程序.我的想法是,如果发送此标头,我将使用json4s,否则我将使用trueaccord序列化器.

我设法创建一个Unmarshaller,它可以根据标头值选择一个请求序列化器:

Unmarshaller.withMaterializer[HttpRequest, T](_ => implicit mat => {
  case request: HttpRequest =>
    val entity = request.entity
    entity.dataBytes.runFold(ByteString.empty)(_ ++ _).map(data => {
      entity.contentType match {
        case `applicationJsonContentType` =>
          val jsFormat = {
            val header = request.headers.find(h => h.name() == jsonFormatHeaderName)
            if (header.isEmpty) "1.0" else header.get.value()
          }

          val charBuffer = Unmarshaller.bestUnmarshallingCharsetFor(entity)
          val jsonText = data.decodeString(charBuffer.nioCharset().name())
          val dto = if(jsFormat == "2.0") {
            write[T](value)(formats) // New Formatter
          } else {
            JsonFormat.fromJsonString[T](jsonText) // Old Formatter …
Run Code Online (Sandbox Code Playgroud)

json scala marshalling unmarshalling akka-http

10
推荐指数
1
解决办法
461
查看次数

Scala中的函数/方法.这是如何运作的?

我是Scala的新手,很难理解声明和使用函数的所有方法.有人可以一步一步解释这里发生了什么吗?

我正在学习介绍Akka HTTP的课程.代码有效,但我不明白路由方法:

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

def route = path("hello") {
    get {
      complete("Hello, World!")
    }
  }
Run Code Online (Sandbox Code Playgroud)

我们正在定义一个route被声明为path(从上面的行导入)的值的方法,但是在path函数内部我们有一些get我不理解的东西.

当我宣布path作为一种方法时,我是否压倒它,或者发生了什么?

如果有人能够逐行解释发生了什么,我会很高兴.并且不介意它是Akka参与.我想知道Scala语法.

================================================== ===============

感谢所有的好答案.我想我明白了!

所以总结一下我的版本吧.

path()是一个想要字符串的函数.它返回另一个想要的函数Directive.在Scala lingo中我们可以做一些currying来直接向返回的函数发送指令.

所以块{}中的所有内容都被发送到path()返回的函数.由于Scala中的一个块总是返回最后一行,我们将get按照我们调用的相同原则返回该行complete.

get也是一个函数,它接受一个参数,可以写成一个块.这相当于写作get(complete("Hello, world")).

再次感谢!

scala function akka-http

10
推荐指数
2
解决办法
703
查看次数

使用Akka-Http进行身份验证

我们正在开发一个iOS应用程序,用户需要使用电子邮件+密码(或手机号码)进行身份验证.我们的后端由几个使用Akka-Http的微服务组成.它需要快速,可扩展,并发,并且身份验证+授权应该适用于我们的多个服务.我正在试图找出使用哪种身份验证方法.Akka-HTTP目前提供Basic Auth和OAuth2的部分实现.

所以起初我们正在考虑基本身份验证(太简单且功能不够),Oauth1(太复杂),所以我们转向OAuth-2.0,因为它是一种标准.

然后我们考虑了AWS Cognito,因为它结合了Oauth-2.0和OpenID Connect,它提供了OAuth2缺乏的身份验证机制. http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html

然后我们意识到OAuth2仅用于使用第三方进行身份验证 - 实际上我们不需要第三方身份验证提供程序 - 也许我们需要自己完成,并且使用Cognito是一种过度杀伤,会在我们之外创建额外的api调用微服务...

所以我读了一些关于创建我们自己的自定义身份验证提供程序,使用WSSE规范:http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html 我也发现这个例子使用Spray,但我是确定它与Akka-Http没有什么不同:http: //danielasfregola.com/2015/06/29/how-to-create-a-spray-custom-authenticator/ 它看起来太简单了,没有令牌过期. ..

所以我的问题是,我错过了什么吗?我应该选择什么方法,在哪里可以找到它的例子?

我觉得我要进入圈子,我们必须从头开始编写我们自己的自定义身份验证提供程序,这有点没有意义.毕竟几乎每个人都需要身份验证,它应该是一个标准.

authentication scala oauth-2.0 amazon-cognito akka-http

9
推荐指数
1
解决办法
1849
查看次数

关闭Akka HTTP应用程序

我有一个正在运行的Akka HTTP应用程序,我想关闭它.

在SBT Ctrl+ 不适用于我(我的shell目前是用于Windows的Git Bash).C

什么是优雅关闭Akka应用程序的推荐方法?

scala akka akka-http

9
推荐指数
1
解决办法
2134
查看次数