Spring Boot Server as a Groovy script.
With this post I am going to start series of post related with my Cheat Sheet. Here is an example of simple Goovy script which initializes and runs Spring Boot server.
Sometimes when I am working with my new POC project, e.g. JavaScript UI app, I need simple and lightweight REST server which I could quickly modify. I wrote this simple Groovy script for that purpose.
Simple REST server (Spring Boot, Groovy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
@Grab('org.springframework.boot:spring-boot-starter-web:1.1.7.RELEASE')
@Grab('org.springframework.boot:spring-boot-starter-actuator:1.1.7.RELEASE')
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
GET /todos/ Reads all tasks.
POST /todos/ Creates a new task.
GET /todo/:id Reads a task.
PUT /todo/:id Updates a task.
DELETE /todo/:id Destroys a task.
**/
@Controller
@RequestMapping(value="/api/todos")
@EnableAutoConfiguration
public class TodosController {
private static final Logger logger = LoggerFactory.getLogger(TodosController.class)
private dataTable = [[
"id": 1,
"title": "Learn Groovy",
"completed": false
],
[
"id": 2,
"title": "Learn ES6",
"completed": false
]]
@RequestMapping(value="/", method=RequestMethod.GET)
@ResponseBody
Map getAllTasks() {
logger.info("Get all todos")
return [
"total": dataTable.size(),
"page": 1,
"perPage": 10,
"todos": dataTable]
}
@RequestMapping(value="/", method=RequestMethod.POST)
@ResponseBody
Integer addTask(@RequestBody Map todo) {
logger.info("Add new todo: ${todo}")
todo.id = dataTable.size() + 1
dataTable.push(todo)
return todo.id
}
@RequestMapping(value="/{todoId}", method=RequestMethod.GET)
@ResponseBody
Map getTask(@PathVariable("todoId")Integer todoId) {
logger.info("Get todo: ${todoId}")
return dataTable.get(todoId - 1)
}
@RequestMapping(value="/{todoId}", method=RequestMethod.PUT)
@ResponseBody
Map updateTask(@PathVariable("todoId")Integer todoId, @RequestBody Map todo) {
logger.info("Update todo: ${todoId} with: ${todo}")
if (dataTable.get(todoId - 1)) {
todo.id = todoId
dataTable.set(todoId - 1, todo)
}
return todo
}
@RequestMapping(value="/{todoId}", method=RequestMethod.DELETE)
@ResponseBody
Map removeTask(@PathVariable("todoId")Integer todoId) {
println("Delete todo: ${todoId}")
if (dataTable.get(todoId - 1)) {
return dataTable.remove(todoId - 1)
}
return false
}
public static void main(String[] args) throws Exception {
SpringApplication.run(TodosController.class, args);
}
}
Short explanation
1) Load required dependencies from maven repository.
1
2
@Grab('org.springframework.boot:spring-boot-starter-web:1.1.7.RELEASE')
@Grab('org.springframework.boot:spring-boot-starter-actuator:1.1.7.RELEASE')
2) Define class/controller/main app in one class. As you see I put RequestMapping
to set base path, you can easily change it by replacing /api/todos
.
1
2
3
4
5
@Controller
@RequestMapping(value="/api/todos")
@EnableAutoConfiguration
public class TodosController {
...
3) As a Data Storage I use List of Maps which I keep in memory. Groovy allows us define Map by using simple syntax.
1
2
3
4
5
6
7
8
9
10
private dataTable = [[
"id": 1,
"title": "Learn Groovy",
"completed": false
],
[
"id": 2,
"title": "Learn ES6",
"completed": false
]]
4) From line 34 to 80 you can find implementation of CRUD methods.
Run and Test
To run this code use next command
1
groovy rest-server.groovy
Here is a simple curl based tests:
Create new task
1
2
3
curl -X POST 'http://localhost:8080/api/todos/' \
-d '{"id":3,"title":"Learn Spring Boot","completed":false}' \
-H "Content-Type: application/json"
Update task by ID
1
2
3
curl -X PUT 'http://localhost:8080/api/todos/3' \
-d '{"id":3,"title":"Learn Spring Boot","completed":true}' \
-H "Content-Type: application/json"
Get all tasks:
1
curl -X GET 'http://localhost:8080/api/todos/'
Get task by ID
1
curl -X GET 'http://localhost:8080/api/todos/1'
Delete task by ID
1
curl -X DELETE 'http://localhost:8080/api/todos/1'
Instead of conclusion
Need to add new path? Just add new method with @RequestMapping and have fun. Have question? Welcome to ask me in comments!