Akka-HTTP creating a directive to create a unique request id?

256 views
Skip to first unread message

kraythe

unread,
Aug 23, 2017, 7:55:56 PM8/23/17
to Akka User List
Greetings, 

I am currently using the low level API but lookign again at the DSL. I have been trying to figure out if there is a way to create a directive that creates a unique request UUID and allows other directives to access that UUID in every sub directive. Basically I want something like 

withRequestId {
  requestId = UUID.randomUUID()
  pathSingleSlash {
    comlete(requestId.toString)
  }
}

I want this to be universal so the outer directive defines the id and the rest of the routes dont have to bother. I dont like copy past code. Any idea if and how this could be done? 

Arnout Engelen

unread,
Aug 24, 2017, 5:08:01 AM8/24/17
to akka...@googlegroups.com
Hello,

You could create a Directive1[UUID] which can then be used like this:

withRequestId { requestId =>
  pathSingleSlash {
    comlete(requestId.toString)
  }
}



Kind regards,

Arnout

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+unsubscribe@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.



--
Arnout Engelen

kraythe

unread,
Aug 24, 2017, 9:52:23 PM8/24/17
to Akka User List
Thanks but I don't understand how I can make the request id available inside the rest of the route. 


On Thursday, August 24, 2017 at 4:08:01 AM UTC-5, Arnout Engelen wrote:
Hello,

You could create a Directive1[UUID] which can then be used like this:

withRequestId { requestId =>
  pathSingleSlash {
    comlete(requestId.toString)
  }
}



Kind regards,

Arnout
On Thu, Aug 24, 2017 at 1:55 AM, kraythe <kra...@gmail.com> wrote:
Greetings, 

I am currently using the low level API but lookign again at the DSL. I have been trying to figure out if there is a way to create a directive that creates a unique request UUID and allows other directives to access that UUID in every sub directive. Basically I want something like 

withRequestId {
  requestId = UUID.randomUUID()
  pathSingleSlash {
    comlete(requestId.toString)
  }
}

I want this to be universal so the outer directive defines the id and the rest of the routes dont have to bother. I dont like copy past code. Any idea if and how this could be done? 

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.

To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

kraythe

unread,
Aug 24, 2017, 9:55:01 PM8/24/17
to Akka User List
I should be more specific. Ok if I do what you say then the request id will be available in the route via being closed over .. I guess I just don't grok how the DSL works. So I will just have to mess with it. My lack of understanding has to do with the type of the argument to withRequestId ... its a function that returns a route? I will mess with this some more. 


On Thursday, August 24, 2017 at 4:08:01 AM UTC-5, Arnout Engelen wrote:
Hello,

You could create a Directive1[UUID] which can then be used like this:

withRequestId { requestId =>
  pathSingleSlash {
    comlete(requestId.toString)
  }
}



Kind regards,

Arnout
On Thu, Aug 24, 2017 at 1:55 AM, kraythe <kra...@gmail.com> wrote:
Greetings, 

I am currently using the low level API but lookign again at the DSL. I have been trying to figure out if there is a way to create a directive that creates a unique request UUID and allows other directives to access that UUID in every sub directive. Basically I want something like 

withRequestId {
  requestId = UUID.randomUUID()
  pathSingleSlash {
    comlete(requestId.toString)
  }
}

I want this to be universal so the outer directive defines the id and the rest of the routes dont have to bother. I dont like copy past code. Any idea if and how this could be done? 

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.

To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

B Wills

unread,
Aug 25, 2017, 1:46:39 PM8/25/17
to Akka User List
Hi,

We do something similar - instead of writing a custom directive, we generate a unique request ID and then put this in the response as a header using the respondWithHeader directive.  For example:

respondWithHeader(RawHeader("Request-ID", requestId)) {
pathPrefix(serviceConfig.getString("self.version")) {
extractClientIP { ip =>

This is in an outer level of our routing structure.  To be a bit more clear:

def routes = {
extractUri { URI =>
val uri = URI.toString()
val requestId = Utils.generateRequestId()

respondWithHeader(RawHeader("Request-ID", requestId)) {
pathPrefix(serviceConfig.getString("self.version")) {
extractClientIP { ip =>
optionalHeaderValueByName("User-Agent") { agent =>
path("path") {
pathEnd {
get {

Jeremy Townson

unread,
Aug 29, 2017, 9:16:08 AM8/29/17
to Akka User List
Because the uuid does not depend on the request in any way, you can map a directive called 'pass' (pass is a a sort of identity directive that does nothing). e.g.

  "directive" should "generate a uuid" in {

    import akka.http.scaladsl.server.Directives.pass

    val uuid = UUID.randomUUID().toString

    val withRequestId: Directive1[String] = pass.tmap(_ => uuid)

    val route = withRequestId { (requestId: String) =>
      complete(requestId)
    }

    Get("http://example.com") ~> route ~> check {
      responseAs[String] shouldBe uuid
    }
  }
Reply all
Reply to author
Forward
0 new messages