armeria icon indicating copy to clipboard operation
armeria copied to clipboard

Add implicit request mapping to `@Head` when the service is mapped to `@Get`

Open ks-yim opened this issue 3 years ago • 6 comments

Many server frameworks(e.g. Spring, express) create an implicit request mapping to HEAD when there's a request handler for GET.

The feature can be useful as client sometimes just want to check the existence of resources without receiving the whole body and almost always the handlers for @Get and @Head should be the same.

Currently, armeria needs 3 annotations to do the same thing.

@Get
@Head
@Path("/some-file")
public HttpResponse someFile(ServiceRequestContext ctx) {
    // ...
    return client.execute(RequestHeaders.of(ctx.method(), "/some-object-storage-path"));
}

ks-yim avatar Jan 20 '22 14:01 ks-yim

may i try this? 🚀

Parkkibum95 avatar Apr 23 '22 12:04 Parkkibum95

@Parkkibum95 Thanks, it seems no one has started working on this 😆

ks-yim avatar Apr 24 '22 13:04 ks-yim

The HEAD method which is identical to GET except that the server MUST NOT return a message-body in the response.

  • https://javadoc.io/static/com.linecorp.armeria/armeria-javadoc/1.16.0/com/linecorp/armeria/common/HttpMethod.html#GET

AFAIK. @get contains all the functions of @head, so If possible, could you explain your intentions in more detail with examples?

cc. @ks-yim

Parkkibum95 avatar Apr 29 '22 14:04 Parkkibum95

@Parkkibum95 Currently, defining a @Get mapping alone in AnnotatedService does not support HEAD requests while other frameworks do.

Imagine the following get mapping definitions:

// Armeria AnnotatedService
@Get("/foo")
public String getFoo() {
    return "foo";
}

// Spring Controller
@GetMapping("/foo")
public String getFoo() {
    return "foo";
}

With the above definitions, sending a HEAD request to the Armeria server gives you 405 error while the Spring sever gives 200(without body) and one can override this behavior by defining an explicit HEAD mapping for the same path.

I wish Armeria showed the same behavior.

ks-yim avatar Apr 30 '22 02:04 ks-yim

i'm really sorry. I couldn't find a way... I think this issue is too hard for me 😞 Once again, I'm so sorry... 😥

Parkkibum95 avatar May 16 '22 07:05 Parkkibum95

@Parkkibum95 No worries, I was thinking of modifying DefaultRoute#apply method.

You may want to see a HEAD request is routed even with a Route which supports HttpMethod#GET but HttpMethod#HEAD, but give a less score to the returned RoutingResult in this case to allow override by defining an explicit @Head mapping.

Not sure if it is the optimal solution but we can give it a try.

ks-yim avatar May 24 '22 11:05 ks-yim

Given Router or Route is often considered a low-level construct for doing a route match, I'd recommend modifying VirtualHost.findServiceConfig(). We could attempt Router.find() once again with GET method when the given RoutingContext's method is HEAD and routing result is NOT_MATCHED.

trustin avatar Feb 22 '23 07:02 trustin