How to create CRUD REST APIs with Spark Framework

© Shutterstock / Shahril KHMD
In this article, Yong Mook Kim, founder at Mkyong.com shows you how to create CRUD REST APIs with Spark Java Framework and Jackson library.
Spark Java runs on an embedded Jetty web server, provide simple APIs to handle HTTP request and response, combine with the Jackson library to serve the JSON output.
I believe this is the simplest, fastest and easiest micro framework to create a REST APIs server.
Tools and technologies used :
- Spark Java 2.6.0
- Jackson 2.8.8
- Java 8
- Maven 3
- cURL (test the REST APIs)
We are going to create the following RESR APIs
POST /user/add - POST request to add an user.
GET /user/:id - GET request to get user by :id.
GET /user - GET request to get all the users.
PUT /user/:id - UPDATE request to update an user by :id.
DELETE /user/:id - DELETE request to delete an user by :id.
1. Project directory
Review the existing project directory layout, nothing special, just a standard Maven directory layout.
2. Project Dependencies
In pom.xml
, declare sparkjava
, jackson
and logback (optional, for logging)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mkyong</groupId> <artifactId>sparkjava</artifactId> <version>1.0-SNAPSHOT</version> <!-- Spark Java need Java 8 --> <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties> <dependencies> <dependency> <groupId>com.sparkjava</groupId> <artifactId>spark-core</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.8.1</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.2</version> </dependency> </dependencies> </project>
3. User & UserService
3.1 A simple POJO.
package com.mkyong.user; public class User { int id; String name; String email; public User(int id, String name, String email) { this.id = id; this.name = name; this.email = email; } //getters, setters and toString() }
3.2 No database involves, just store all users’ objects into a local variable.
package com.mkyong.user; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; public class UserService { public static Map users = new HashMap<>(); private static final AtomicInteger count = new AtomicInteger(0); public User findById(String id) { return users.get(id); } public User add(String name, String email) { int currentId = count.incrementAndGet(); User user = new User(currentId, name, email); users.put(String.valueOf(currentId), user); return user; } public User update(String id, String name, String email) { User user = users.get(id); if (name != null) { user.setName(name); } if (email != null) { user.setEmail(email); } users.put(id, user); return user; } public void delete(String id) { users.remove(id); } public List findAll() { return new ArrayList<>(users.values()); } public UserService() { } }
4. Spark Java + Jackson
Time to code. Review the comments for self-explanatory.
package com.mkyong; import com.fasterxml.jackson.databind.ObjectMapper; import com.mkyong.user.User; import com.mkyong.user.UserService; import java.util.List; import static spark.Spark.get; import static spark.Spark.port; import static spark.Spark.post; import static spark.Spark.put; import static spark.Spark.delete; public class Main { private static UserService userService = new UserService(); private static ObjectMapper om = new ObjectMapper(); public static void main(String[] args) { // Start embedded server at this port port(8080); // Main Page, welcome get("/", (request, response) -> "Welcome"); // POST - Add an user post("/user/add", (request, response) -> { String name = request.queryParams("name"); String email = request.queryParams("email"); User user = userService.add(name, email); response.status(201); // 201 Created return om.writeValueAsString(user); }); // GET - Give me user with this id get("/user/:id", (request, response) -> { User user = userService.findById(request.params(":id")); if (user != null) { return om.writeValueAsString(user); } else { response.status(404); // 404 Not found return om.writeValueAsString("user not found"); } }); // Get - Give me all users get("/user", (request, response) -> { List result = userService.findAll(); if (result.isEmpty()) { return om.writeValueAsString("user not found"); } else { return om.writeValueAsString(userService.findAll()); } }); // PUT - Update user put("/user/:id", (request, response) -> { String id = request.params(":id"); User user = userService.findById(id); if (user != null) { String name = request.queryParams("name"); String email = request.queryParams("email"); userService.update(id, name, email); return om.writeValueAsString("user with id " + id + " is updated!"); } else { response.status(404); return om.writeValueAsString("user not found"); } }); // DELETE - delete user delete("/user/:id", (request, response) -> { String id = request.params(":id"); User user = userService.findById(id); if (user != null) { userService.delete(id); return om.writeValueAsString("user with id " + id + " is deleted!"); } else { response.status(404); return om.writeValueAsString("user not found"); } }); } }
Done, let’s test it.
5. Test with cURL
Start Main.java
and the embedded Jetty server will start as well. Those REST APIs are ready to test. Open a terminal and test the REST APIs with cURL.
//Start Main.java... 2017-05-26 16:18:49 DEBUG spark.route.Routes - Adds route: get, /, [email protected] 2017-05-26 16:18:49 DEBUG spark.route.Routes - Adds route: post, /user/add, [email protected] 2017-05-26 16:18:49 DEBUG spark.route.Routes - Adds route: get, /user/:id, [email protected] 2017-05-26 16:18:49 DEBUG spark.route.Routes - Adds route: get, /user, [email protected] 2017-05-26 16:18:49 DEBUG spark.route.Routes - Adds route: put, /user/:id, [email protected] 2017-05-26 16:18:49 DEBUG spark.route.Routes - Adds route: delete, /user/:id, [email protected]0a 2017-05-26 16:18:49 INFO s.e.jetty.EmbeddedJettyServer - == Spark has ignited ... 2017-05-26 16:18:49 INFO s.e.jetty.EmbeddedJettyServer - >> Listening on 0.0.0.0:8080
Let’s test the following REST APIs :
POST /user/add - POST request to add an user. GET /user/:id - GET request to get user by :id. GET /user - GET request to get all the users. PUT /user/:id - UPDATE request to update an user by :id. DELETE /user/:id - DELETE request to delete an user by :id.
5.1 POST /user/add
# Add user 'mkyong' $ curl -X POST -d "name=mkyong&[email protected]" http://localhost:8080/user/add {"id":1,"name":"mkyong","email":"[email protected]"} # Add user 'jack' $ curl -X POST -d "name=jack&[email protected]" http://localhost:8080/user/add {"id":2,"name":"jack","email":"[email protected]"}
5.2 GET /user/:id & GET /user
# Get user where id = 1 $ curl http://localhost:8080/user/1 { "id" : 1, "name" : "mkyong", "email" : "[email protected]" } # Get user where id = 2 $ curl http://localhost:8080/user/2 { "id" : 2, "name" : "jack", "email" : "[email protected]" } # Get all users $ curl http://localhost:8080/user [ { "id" : 1, "name" : "mkyong", "email" : "[email protected]" }, { "id" : 2, "name" : "jack", "email" : "[email protected]" } ]
5.3 PUT /user/:id
# Update $ curl -X PUT -d "name=jack2&[email protected]" http://localhost:8080/user/2 "user with id 2 is updated!" # Get user where id = 2 $ curl http://localhost:8080/user/2 { "id" : 2, "name" : "jack2", "email" : "[email protected]" }
5.4 DELETE /user/:id
# Delete user where id = 2 $ curl -X DELETE http://localhost:8080/user/2 "user with id 2 is deleted!" # User id = 2 is no longer exists $ curl http://localhost:8080/user/2 "user not found" # Get all users $ curl http://localhost:8080/user [ { "id" : 1, "name" : "mkyong", "email" : "[email protected]" } ]
Download source code
References
This post was created by mkyong.com.
asap
the link to the source file is broken
Thank you for letting us know, we’ll take care of it.