San Jaisy
San Jaisy

Reputation: 17048

Micronaut declarative HTTP client not working for the HTTP verbs

I have the below interface as the common Http action for GET, PUT, POST and DELETE

@Validated
@ExecuteOn(TaskExecutors.BLOCKING)
public interface IHttpAction<T, R> {

    @Get(value = "/{?searchCriteria*}")
    HttpResponse<?> find(@QueryValue T searchCriteria);

    @Get(uri = "/{id}")
    HttpResponse<?> get(@PathVariable @Nonnull UUID id);

    HttpResponse<?> post(@Body T request);

    @Put(uri = "/{id}")
    HttpResponse<?> put(@NotNull UUID id, @Body T request);

    HttpResponse<?> delete(@NotNull UUID id);
}

Now I have the micronuat declarative client as below

public class TestHttpClient {
    @Client("/tag")
    public interface TagHttpClient extends IHttpAction<TagRequest, TagResponse> { }
}

Now I am writing Test case as below

@MicronautTest
public class TagControllerTest {
private final TestHttpClient.TagHttpClient testHttpClient;

    public TagControllerTest(TestHttpClient.TagHttpClient testHttpClient) {
        this.testHttpClient = testHttpClient;
    }

    @Test
    @DisplayName("Should create a tag with valid name")
    void shouldCreateATagWithValidName() {

        var result =  this.testHttpClient.get(UUID.randomUUID());
        Assertions.assertNotNull(result);
    }
}

The controller

@Controller("/tag")
@Version("1")
public class TagController implements IHttpAction<TagRequest, TagResponse> {
    private final IServiceAction<TagRequest, TagResponse> iServiceAction;

    public TagController(IServiceAction<TagRequest, TagResponse> iServiceAction) {
        this.iServiceAction = iServiceAction;
    }

    @Override
    public HttpResponse<?> find(@QueryValue TagRequest searchCriteria) {
        var result = this.iServiceAction.find(searchCriteria);
        return result.match(()-> HttpResponse.ok(result.value), ()->HttpResponse.notFound(result.exception.getMessage()));
    }

    @Override
    public HttpResponse<?> get(@Nonnull UUID id) {
        var result = this.iServiceAction.get(id);
        return result.match(()-> HttpResponse.ok(result.value), ()->HttpResponse.notFound(result.exception.getMessage()));
    }

  // Other methods
   
}

When I am running the test project, with the method this.testHttpClient.get(UUID.randomUUID()); it should come to the get controller method, however, the call was to the find end point.

The logs from the HTTP client

15:01:19.253 [Test worker] INFO  i.m.c.DefaultApplicationContext$RuntimeConfiguredEnvironment - Established active environments: [test]
15:01:19.778 [default-nioEventLoopGroup-1-2] DEBUG i.m.h.client.netty.DefaultHttpClient - Sending HTTP GET to http://localhost:56407/tag/?arg0=4311ca00-345b-4393-a2b5-3ef43f9b14f3

The below CURL

curl --location 'http://localhost:8080/tag/0ea13638-b9d7-11ef-9cd2-0242ac120002'

works perfectly with postman

Upvotes: 0

Views: 72

Answers (3)

Sergio del Amo
Sergio del Amo

Reputation: 78096

log the http client to see what is doing. Add to logback.xml

<logger name="io.micronaut.http.client" level="TRACE"/>

Upvotes: 0

San Jaisy
San Jaisy

Reputation: 17048

I have to decorate it with path variable with name

@Get(uri = "/{id}")
HttpResponse<?> get(@PathVariable(name = "id") @Nonnull UUID id);

Upvotes: 0

Robert Sj&#246;dahl
Robert Sj&#246;dahl

Reputation: 754

The Get method in the interface is missing a @PathVariable. You can see in the log that the id ends up as a query parameter instead.

Upvotes: 0

Related Questions