https://kotlinlang.org logo
#http4k
Title
# http4k
d

David Hamilton

03/22/2022, 6:38 PM
Hi. I'm trying to return content based on (optional)
Accept
header provided by client, providing json content only when specifically requested by the client. However both my routes are now returning
405
whereas the fallback handler worked fine without the nested route:
Copy code
"/mappings" bind routes(
                Method.GET to routes(
                    header("Accept", "application/json") bind ingressTracingLoggingFilter.then(mappingsAdminJsonHandler),
                    Fallback bind ingressTracingLoggingFilter.then(mappingsAdminReportHandler)
                ),
                <http://Method.POST|Method.POST> to someOtherHandler
            ),
What am I doing wrong?
d

dave

03/22/2022, 6:54 PM
first question - are you sure that the content type being sent hasn't got the charset on it? can you debug and show the request being sent?
d

David Hamilton

03/23/2022, 8:31 AM
The test uses http to make the call, e.g.:
Copy code
Request(Method.GET, "<http://localhost>:$servicePort$path")
    .header("Accept", "application/json")
    .execute()
So surely that would match the filter? Also, why 405? Surely it should be handled by the
Fallback
section? And why has the non-JSON test, which should be handled by the Fallback anyway suddenly started failing with 405 responses? I'll investigate further this morning
I completely get your point about charsets through. Is there a better/canonical way of doing accept header checking / content negotiation?
To clarify my original message, this GET routing (without the accept filter) used to work in the test for non-JSON content:
Copy code
"/mappings" bind routes(
                Method.GET to  ingressTracingLoggingFilter.then(mappingsAdminReportHandler),
                <http://Method.POST|Method.POST> to someOtherHandler
            ),
But now that non-JSON test also fails with 405 response
Update: Separating completely the routes for the differing Accept rules works (passes the test case) with no further changes:
Copy code
"/mappings" bind routes(
    Method.GET.and(header("Accept", "application/json")) bind ingressTracingLoggingFilter.then(mappingsAdminJsonHandler),
),
"/mappings" bind routes(
    Method.GET to ingressTracingLoggingFilter.then(mappingsAdminReportHandler),
),
So why does that work, and not the nested header filter and fallback?
d

dave

03/24/2022, 6:25 AM
405 normally occurs when we match the route but not the verb. . Could you put a quick gist together with a runnable example - as there's a lot of detail here that am probably missing
Your content negotiation approach is fine btw
d

David Hamilton

03/25/2022, 10:42 AM
Sure, I'll work up a simple example 👍
4 Views