Request parameters
A client sends data not only in the request body but also in the address itself: /articles/5 is a path variable, /search?q=java&page=2 holds query string parameters (everything after the ? sign). Some information also arrives in headers. Micronaut maps all of this onto method parameters and converts the strings to the right types for you.
Where values come from
| Annotation | Source of the value | Example address |
|---|---|---|
@PathVariable | The part of the path in curly braces | /search/tag/java |
@QueryValue | The query string after ? | /search?q=java |
@Header | A request header | User-Agent: curl/8.21.0 |
For a path variable the annotation is optional: Micronaut fills a parameter whose name matches {id} in the address by itself. The annotation just makes the code clearer.
A search controller
Create a file for searching the blog:
// src/main/java/com/example/SearchController.java
package com.example;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Header;
import io.micronaut.http.annotation.PathVariable;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.annotation.QueryValue;
@Controller("/search")
@Produces(MediaType.TEXT_PLAIN)
public class SearchController {
@Get
public String search(@QueryValue String q,
@QueryValue(defaultValue = "1") int page) {
return "Searching for '" + q + "', page " + page;
}
@Get("/tag/{tag}")
public String byTag(@PathVariable String tag, @QueryValue @Nullable String sort) {
return "Tag " + tag + ", sort: " + (sort == null ? "none" : sort);
}
@Get("/client")
public String client(@Header("User-Agent") String userAgent) {
return "Your client: " + userAgent;
}
}The q parameter is required, page has a default value, and sort is marked @Nullable: when it is missing, you get null. The string "2" from the address becomes an int automatically.
Trying it out
curl "http://localhost:8080/search?q=micronaut"
curl "http://localhost:8080/search?q=micronaut&page=2"
curl "http://localhost:8080/search/tag/java?sort=new"
curl http://localhost:8080/search/clientSearching for 'micronaut', page 1
Searching for 'micronaut', page 2
Tag java, sort: new
Your client: curl/8.21.0Put an address containing & in quotes, otherwise the shell splits it into two commands.
Wrong type
If a value cannot be converted to the parameter's type, the method is not called and the client gets 400:
curl "http://localhost:8080/search?q=x&page=two"{"_links":{"self":[{"href":"/search?q=x&page=two","templated":false}]},"_embedded":{"errors":[{"message":"Failed to convert argument [page] for value [two] due to: For input string: \"two\"","path":"/page"}]},"message":"Bad Request"}The same happens with /articles/abc when the id parameter is declared as Long.
Common mistake
Micronaut treats a parameter without @Nullable and without a default value as required. A request without it gets 400:
curl http://localhost:8080/search{"_links":{"self":[{"href":"/search","templated":false}]},"_embedded":{"errors":[{"message":"Required QueryValue [q] not specified","path":"/q"}]},"message":"Bad Request"}If the parameter is optional by meaning, add @Nullable (from the io.micronaut.core.annotation package) or a defaultValue.