6.12.1 Using the @Body Annotation
To parse the request body, you first need to indicate to Micronaut the parameter which will receive the data. This is done with the Body annotation.
The following example implements a simple echo server that echos the body sent in the request:
Using the @Body annotation
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpResponse;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Post;
import io.reactivex.Flowable;
import io.reactivex.Single;
import javax.validation.constraints.Size;
@Post(value = "/echo", consumes = MediaType.TEXT_PLAIN) (1)
String echo(@Size(max = 1024) @Body String text) { (2)
return text; (3)
}
Using the @Body annotation
import io.micronaut.http.MediaType
import io.micronaut.http.MutableHttpResponse
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Post
import io.reactivex.Flowable
import io.reactivex.Single
import javax.validation.constraints.Size
@Post(value = "/echo", consumes = MediaType.TEXT_PLAIN) (1)
String echo(@Size(max = 1024) @Body String text) { (2)
text (3)
}
Using the @Body annotation
import io.micronaut.http.HttpResponse
import io.micronaut.http.MediaType
import io.micronaut.http.MutableHttpResponse
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Post
import io.reactivex.Flowable
import io.reactivex.Single
import javax.validation.constraints.Size
@Controller("/receive")
open class MessageController {
@Post(value = "/echo", consumes = [MediaType.TEXT_PLAIN]) (1)
open fun echo(@Size(max = 1024) @Body text: String): String { (2)
return text (3)
}
}
1 | The Post annotation is used with a MediaType of text/plain (the default is application/json ). |
2 | The Body annotation is used with a javax.validation.constraints.Size that limits the size of the body to at most 1MB. This constraint does not limit the amount of data read/buffered by the server. |
3 | The body is returned as the result of the method |
Note that reading the request body is done in a non-blocking manner in that the request contents are read as the data becomes available and accumulated into the String passed to the method.
The micronaut.server.maxRequestSize setting in application.yml will limit the size of the data (the default maximum request size is 10MB) read/buffered by the server. @Size is not a replacement for this setting. |
Regardless of the limit, for a large amount of data accumulating the data into a String in-memory may lead to memory strain on the server. A better approach is to include a Reactive library in your project (such as RxJava 2.x
, Reactor
or Akka
) that supports the Reactive streams implementation and stream the data it becomes available:
Using RxJava 2 to Read the request body
@Post(value = "/echo-flow", consumes = MediaType.TEXT_PLAIN) (1)
Single<MutableHttpResponse<String>> echoFlow(@Body Flowable<String> text) { (2)
return text.collect(StringBuffer::new, StringBuffer::append) (3)
.map(buffer ->
HttpResponse.ok(buffer.toString())
);
}
Using RxJava 2 to Read the request body
@Post(value = "/echo-flow", consumes = MediaType.TEXT_PLAIN) (1)
Single<MutableHttpResponse<String>> echoFlow(@Body Flowable<String> text) { (2)
return text.collect({ x -> new StringBuffer()}, { StringBuffer sb, String s -> sb.append(s)}) (3)
.map({ buffer ->
HttpResponse.ok(buffer.toString())
});
}
Using RxJava 2 to Read the request body
@Post(value = "/echo-flow", consumes = [MediaType.TEXT_PLAIN]) (1)
open fun echoFlow(@Body text: Flowable<String>): Single<MutableHttpResponse<String>> { (2)
return text.collect({ StringBuffer() }, { obj, str -> obj.append(str) }) (3)
.map { buffer -> HttpResponse.ok(buffer.toString()) }
}
1 | In this case the method is altered to receive and return an RxJava 2.x Flowable type |
2 | A Single is returned so that Micronaut will only emit the response once the operation completes without blocking. |
3 | The collect method is used to accumulate the data in this simulated example, but it could for example write the data to logging service, database or whatever chunk by chunk |
Body arguments of types that do not require conversion will cause Micronaut to skip decoding of the request! |