The main idea behind creating a RESTful application is that you will create logical resources (GET, POST, UPDATE and DELETE) consumed by clients usign HTTP request.
This resources should be nouns no verbs. In this example we will create a RESTful application using a person resource.
So we can have:
- GET /persons - Retrieves a list of persons
- GET /persons/1234 - Retrieves a specific person
- POST /persons - Creates a new person
- PUT /persons/1234 - Updates #1234 person
- DELETE /persons/1234 - Deletes #1234 person
NOTE: If you need to know what tools you need to have installed in your computer in order to create a Spring Boot basic project, please refer my previous post: Spring Boot
Then execute this command in your terminal.
spring init --dependencies=web --language=groovy --build=gradle spring-boot-restful
This is the build.gradle file
generated:
buildscript {
ext {
springBootVersion = '1.5.9.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'groovy'
apply plugin: 'org.springframework.boot'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.codehaus.groovy:groovy')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
Here is how looks our person model
package com.jos.dem.springboot.restful.model
class Person {
String nickname
String email
}
Netx let’s create a PersonService
to delegate all operations needed
package com.jos.dem.springboot.restful.service
import com.jos.dem.springboot.restful.model.Person
interface PersonService {
List<Person> getPersons()
Person getPerson(String uuid)
Person create(Person person)
Person update(Person person)
Person delete(String uuid)
}
Then let’s look our controller who receives client’s request and provide client’s response
package com.jos.dem.springboot.restful.controller
import static org.springframework.web.bind.annotation.RequestMethod.GET
import static org.springframework.web.bind.annotation.RequestMethod.POST
import static org.springframework.web.bind.annotation.RequestMethod.PUT
import static org.springframework.web.bind.annotation.RequestMethod.DELETE
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.http.HttpStatus
import com.jos.dem.springboot.restful.service.PersonService
import com.jos.dem.springboot.restful.model.Person
import com.jos.dem.springboot.restful.exception.BusinessException
import org.slf4j.Logger
import org.slf4j.LoggerFactory
@RestController
@RequestMapping('/persons/**')
class PersonController {
Logger log = LoggerFactory.getLogger(this.class)
@Autowired
PersonService personService
@RequestMapping(method=GET)
@ResponseBody
List<Person> getPersons(){
log.info 'Listing all persons'
personService.getPersons()
}
@RequestMapping(value='/{uuid}' ,method=GET)
@ResponseBody
Person getPerson(@PathVariable String uuid){
log.info "Getting person by uuid: ${uuid}"
personService.getPerson(uuid)
}
@RequestMapping(method=POST, consumes='application/json')
@ResponseBody
Person createPerson(@RequestBody Person person){
log.info "Creating new person: ${person.nickname}"
personService.create(person)
}
@RequestMapping(method=PUT, consumes='application/json')
@ResponseBody
Person updatePerson(@RequestBody Person person){
log.info "Updating person: ${person.nickname}"
personService.update(person)
}
@RequestMapping(value='/{uuid}', method=DELETE)
@ResponseBody
Person deletePerson(@PathVariable String uuid){
log.info "Deleting person with uuid: ${uuid}"
personService.delete(uuid)
}
@ResponseStatus(value=HttpStatus.UNAUTHORIZED)
@ExceptionHandler(BusinessException.class)
ResponseEntity<String> handleException(BusinessException be){
return new ResponseEntity<String>(be.message, HttpStatus.UNAUTHORIZED)
}
}
ExceptionHandler
is a strategy to catch any exception that possibly occurs, receives an BusinessException
who it is actually a wrapper exception. For more information regading this strategy, please refer my previous post: Spring Boot AOP
To get list of persons:
curl -v 'http://localhost:8080/persons/'
To get a person by uuid:
curl -v 'http://localhost:8080/persons/1234'
To create a new person:
curl -H "Content-Type: application/json" -v -X POST -d '{"nickname":"josdem","email":"joseluis.delacruz@gmai.com"}' 'http://localhost:8080/persons/'
To update a person:
curl -H "Content-Type: application/json" -v -X PUT -d '{"nickname":"josdem","email":"joseluis.delacruz@gmai.com"}' 'http://localhost:8080/persons/'
To delete a person by uuid:
curl -v -X DELETE 'http://localhost:8080/persons/1234'
This is how get all persons response looks like:
Trying 127.0.0.1...
TCP_NODELAY set
Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /persons/ HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.55.1
> Accept: */*
< HTTP/1.1 200
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sat, 27 Jan 2018 20:28:31 GMT
Connection #0 to host localhost left intact
[{"nickname":"josdem","email":"joseluis.delacruz@gmail.com"}]
To Download the Project:
git clone https://github.com/josdem/spring-boot-restful.git
To Run the project:
gradle bootRun