Skip to content
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

Add a way to get the template for the current request #1191

Open
Azquelt opened this issue Nov 14, 2023 · 13 comments
Open

Add a way to get the template for the current request #1191

Azquelt opened this issue Nov 14, 2023 · 13 comments

Comments

@Azquelt
Copy link
Member

Azquelt commented Nov 14, 2023

I couldn't find a way to get the full template used to match the current request against a rest resource.

Background

I'm working on support for MicroProfile OpenTelemetry, which integrates with Jakarta Rest to automatically create traces when rest requests are served. These traces can be aggregated from many microservices so that you can look at one incoming request and see all the microservices which were involved in serving the response.

One of the suggested pieces of information to add to each trace is what they call the "route":

The matched route, that is, the path template in the format used by the respective server framework.
OpenTelemetry Specification

So, for example, if I had this resource:

@Path("foo")
public class FooResource {

    @Path("{id}")
    @GET
    public String getFoo(@PathParam("id") String id) {
        /* ... */
    }
}

For a request to /foo/12345, I'd want to use the string /foo/{id} as the value for http.route. (Assuming an application path of /)

Storing this information allows me to search all the aggregated traces and find ones which involved a request to this endpoint. For Jakarta REST, I think it's usually equivalent to the class + method pair used to serve the request, but conceptually, the idea of the path template is more easily understandable and applicable across different languages and frameworks.

Problem

Although this is information which any Jakarta Rest implementation needs to process to serve a request, I couldn't find a way for an application or a filter to get or to reliably construct this string using the API.

For a simple case where only one resource class is involved, I can inject ResourceInfo to get the class and method and use reflection to look at the @Path annotations on both, but this approach doesn't work if sub-resources are used to serve the request.

Would it be possible to add to the API a way to get the template used to serve the current request, or expose the information needed to reconstruct it? I think this could be done by either:

  • adding a new method to UriInfo to get the template directly
  • extending ResourceInfo so that if a request is served by a subresource, then information about preceding resource locators is also available
@jim-krueger
Copy link
Contributor

Thanks @Azquelt. Unless there is some other way to get this information in a sub-resource scenario, perhaps ResourceInfo should have a getSuperResourceInfo() method added to it that would return null or the ResourceInfo object for the super resource class. Perhaps we'll get a better suggestion here.

@spericas
Copy link
Contributor

@Azquelt Seems like a useful addition. Simple cases should be possible today with some introspection, at least those without resource locators.

@jim-krueger I agree. However, such a method would require creating a new instance of ResourceInfo for every request, as you could reach the same resource using different locators. Not sure about the implementation implications.

@jansupol Any concerns from an implementation point of view?

@jamezp
Copy link
Contributor

jamezp commented Nov 21, 2023

I just want to add a +1 to this. It's come up for WildFly before as well and the workarounds aren't ideal as they usually rely on implementation details.

@jansupol
Copy link
Contributor

@Azquelt Should @ApplicationPath be included?

@Azquelt
Copy link
Member Author

Azquelt commented Jan 16, 2024

@jansupol For my use case yes, I would want to include both the ApplicationPath and any context root.

I don't have a strong opinion as to whether that should be returned from the API, as long as it's possible for someone to construct the full template including the application path and context root.

@mkarg
Copy link
Contributor

mkarg commented Jan 17, 2024

This sounds like a useful addition, but regarding your original use case I wonder if the route really is the template. Isn't it the actual resource?

@Azquelt
Copy link
Member Author

Azquelt commented Jan 18, 2024

I'm not sure what you mean by "the actual resource" here.

The concept of the "route" is defined by the OpenTelemetry Specification as the path template (in whatever format is used by the server framework). I'm asking for a portable way to get that information from Jakarta REST.

@jansupol
Copy link
Contributor

I am +1 for this, but we need to find a proper name for this. Right I can see the following suggestions:

  • request template
  • path template
  • route

@jamezp
Copy link
Contributor

jamezp commented Jan 19, 2024

I think I like "request template" best, however I do question if that doesn't fit an "@ApplicationPath". In which case, I guess "path template" might make the most sense.

I have no real strong preference though.

@mkarg
Copy link
Contributor

mkarg commented Jan 19, 2024

I'm not sure what you mean by "the actual resource" here. The concept of the "route" is defined by the OpenTelemetry Specification as the path template (in whatever format is used by the server framework). I'm asking for a portable way to get that information from Jakarta REST.

The resource is https://foo/bar and the template is https://foo/{id}.

With the actual value (bar) I would call it "resource path", with the placeholder ({id}) I would call it "resource template".

@jamezp
Copy link
Contributor

jamezp commented Jan 19, 2024

That's a good point on "path" vs "template". I guess to me something like resourceTemplate() makes the most sense. I suppose it won't always be a template, but it also won't always be a path.

@mkarg
Copy link
Contributor

mkarg commented Jan 19, 2024

It sounds strange, but a template is even a template if it does not contain any placeholders at all. So we can call it resourceTemplate if it could contain placeholders.

@jamezp
Copy link
Contributor

jamezp commented Jan 19, 2024

It sounds strange, but a template is even a template if it does not contain any placeholders at all. So we can call it resourceTemplate if it could contain placeholders.

This makes the most sense to me then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants