Rest controller

The @RestController annotation is designed for building a RESTful applications. Usually, it implements CRUD of resources via http.

Unlike the @Controller it doesn't follows mvc pattern. Instead of returning a view, a rest controller returns some data in json format (or xml by desire). Spring Boot automatically converts objects from/to json.

@RequestMapping("/myapi/1.0")
@RestController
class TestRestController {

    @Autowired
    lateinit var srvApi: ContentsApiService

    @GetMapping("/empty")
    @ResponseBody
    fun emptyObject()= "{}"

    @PostMapping("/example1/{id}")
    fun example1(@RequestParam param1:Int, 
                 @RequestParam(defaultValue = "txt") param2: String, 
                 @PathVariable id: Long) 
         =  try { 
       ...
    } catch (e: Exception) {
        SrvResponse<Any>(e)
    }

    @PostMapping("/example2")
    fun example2(@RequestBody person: Person) 
         = SrvResponse(person.apply { nameFirst += "1"; nameLast += 1 })

    @ExceptionHandler(Exception::class)
    fun errorHandler(e: Exception): SrvResponse<Any> {
        return SrvResponse(e)
    }
}

request parameters

To use parameters with @ParamRequest annotation, the client must send the request data in the form of "x-www-form-urlencoded" or append it to the URL. Otherwise, these parameters will be empty. For example, in the jQuery library, this is the default content type.

@PostMapping("/example3")
@ResponseBody
fun example3(@RequestParam param1: Int, 
             @RequestParam(defaultValue = "txt") param2: String) =
        "{a: ${param1}, b: ${param2}}"

$.ajax({ type: 'POST', url: "/myapi/1.0/example3", data: {param1: 5 , param2: "txt-34"}, ... });

To use parameter with @RequestBody annotation for automatically convert to Java/Kotlin object from json, client must send data as "application/json" content type.

@PostMapping("/example2")
fun example2(@RequestBody body: Person) =
    SrvResponse(body.apply { firstName += "1"; lastName += 1 })

$.ajax({ type: 'POST', url: "/myapi/1.0/example2", data : JSON.stringify({ firstName : "Ron", lastName : "Weasley" }), contentType: "application/json", ... }); /* Without content type you will get error "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported" */

response

By default, any return data will be converted to json. Usually a class like SrvResponse is used as a response object.

class SrvResponse<T>(
    var data: T? = null,
    var code: Int = 0,
    var message: String = "ok",
    var error: String = ""
) {
constructor(e: Throwable, msg: String = e.message ?: "unknown error"): 
        this(null, -1, msg, e.message ?: msg)

The @ResponseBody annotation is used for returning json string directly.

@GetMapping("/empty")
@ResponseBody
fun emptyObject()="{}"

Spring Boot does not generate an empty object "{}" if the method has no return value. Therefore, an error may occur if the client expects a JSON response. For example, the jquery library will have a "parsererror" message.

@GetMapping("/empty")
fun emptyObject(){}

function doEmpty () { $.ajax({ // js type: 'GET', url: "/myapi/1.0/empty", dataType: "json", success: function(response) { console.log("response = ", response); }, error: function(errdata) { console.log("err = ", errdata.statusText); } });