Search code examples
javatype-conversionmicronaut

Micronaut automatic conversion of HTTP request parameters


I am currently struggling trying to setup micronaut in order to automatically convert parameters from the http request uri into pojos.

Specifically I want to achieve something like that:

@Controller
public class FooBarBazController {

    @Get("/{foo}/{bar}")
    public Baz doSomething(Foo foo, Bar bar) {
        return new Baz(foo, bar);
    }

}

Assuming Foo and Bar can be constructed from a string value.

The only response I got from the server is

{
  "_links": {
    "self": {
      "href": "/forever/young",
      "templated": false
    }
  },
  "message": "Required argument [Foo foo] not specified",
  "path": "/foo"
}

I have already tried the following:

  • Define a @Factory that registers two beans: TypeConverter<String, Foo> and TypeConverter<String, Bar>
  • Define the parameters as @QueryValue("foo") and @QueryValue("bar") respectively
  • Define the parameters as @PathVariable("foo") and @PathVariable("bar") respectively

None of that seems to help, and I cannot find any reference online that resemble my problem.

Does anybody know how can I instruct the framework to perform the automatic conversion and binding?

Thanks.


Solution

  • With Micronaut 1.3 the only thing required is to define a TypeConverter for Foo and Bar:

    @Singleton
    public class FooTypeConverter implements TypeConverter<String, Foo> {
        @Override
        public Optional<Foo> convert(String fooString, Class<Foo> targetType, ConversionContext context) {
            return new Foo(fooString);
        }
    }
    

    ...

    @Singleton
    public class BarTypeConverter implements TypeConverter<String, Bar> {
        @Override
        public Optional<Bar> convert(String barString, Class<Bar> targetType, ConversionContext context) {
            return new Bar(barString);
        }
    }
    

    That's it.

    In your controller, you can then just use Foo and Bar like any other type that Micronaut knows about:

    @Get("/foo/{foo}")
    public HttpResponse<FooResponse> getFoo(@PathVariable Foo foo) {
        ...
    }
    

    ...

    @Get("/bar/{bar}")
    public HttpResponse<BarResponse> getBar(@PathVariable Bar bar) {
        ...
    }