New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
X-Request-ID Middleware #3487
X-Request-ID Middleware #3487
Conversation
[ ] Attribute Key and append the UUID to both Request and Response via the attribute Key |
I think this is on the right track. Since @voidcontext has been studying the middlewares in such depth, I'm curious what he thinks about the overloads, so we can steer toward some consistency.
def apply[G[_], F[_]]( | ||
fk: F ~> G, | ||
headerName: CIString = requestIdHeader, | ||
genReqId: Option[F[UUID]] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder about two constructors here instead of this optional parameter, because if we provide some generator, I don't think we need the Sync
constraint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okidoke, I'll mess around with the method types and see if I can get something nice working.
} | ||
} | ||
|
||
def httpApp[F[_]: Sync](httpApp: HttpApp[F]): HttpApp[F] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@voidocontext was moving toward having an httpApp
and httpRoutes
object, and then providing overloads off of those. Maybe that's a good idea here, particularly if we do the second constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't suppose you have an example? Tried doing some snooping on @ voidocontext
, but couldn't find anything.
Made the change 611c898 , this "feels" more ergonomic, but might be difficult to maintain in future.
Really appreciate the help so far! However I might need a bit more instruction (maybe method signatures) to get this PR over the line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
He discussed it on #2402. I don't think there are any examples yet, but I understood him to mean something like:
object httpApp {
def apply(headerName: CIString)(httpApp: HttpApp[F]): HttpApp[F] = ???
def apply[F[_]: Sync](
headerName: CIString = requestIdHeader,
genReqId: F[UUID]
)(httpApp: HttpApp[F]): HttpApp[F] = ???
}
Since you're overloading apply
, it doesn't really save much. But if you were giving everything its own name, that technique would give you a nice namespace for the parallel methods to all be called the same thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to apply the same pattern that we're going to use for all the other middleware.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for the delay, I got swamped with other things, but indeed this is what I had in mind when I suggested this approach.
genReqId now effectively has a default arg
Hi @ChristopherDavenport , re:
Are you referring to being able to override the |
I think he's referring to the vault on the request. Here's an example from a client middleware: private val redirectUrisKey = Key.newKey[IO, List[Uri]].unsafeRunSync
/**
* Get the redirection URIs for a `response`.
* Excludes the initial request URI
*/
def getRedirectUris[F[_]](response: Response[F]): List[Uri] =
response.attributes.lookup(redirectUrisKey).getOrElse(Nil) Both the request and response have attributes, which is a I'm not sure if it's that useful on the request, since it can be fetched as a header. Although another version of this middleware that passes them along as attributes instead of adding synthetic headers could be appealing. I don't mean to speak for Chris, but I happened to be awake. I'll let him set us both right. |
Made the following changes:
Not added anything to the request/response attribute, as I don't think I would use that feature, so it makes it difficult to design/implement. If we feel strongly about it though, happy to add it, but would need additional instruction as to what to use for the attribute key. |
I feel very strongly about applying it as an attribute to all requests and responses.
|
Okidoke, added an implementation + test. Please let me know if you folks want anything else changing. |
I think this is another one we can backport and release in 0.21.x. |
Added to the 0.21.x series. Thanks! |
Implements #3485 .
TODO
UUID.randomUUID()
blocking (option 2 of #3485 (comment))