Building a Basic CRUD RESTful Spring Boot MVC Application: Getting Started With Java Spring
In this article, I will show you how to extend its features by creating a Basic CRUD RESTFul Spring boot MVC application through an example.
Join the DZone community and get the full member experience.
Join For FreeWe already know how to build a Simple Spring boot web project from the scratch. In this article, I will show you how to extend its features by creating a Basic CRUD RESTFul Spring boot MVC application through an example.
What Does RESTful Mean?
RESTful (Representational State Transfer) is an architectural design pattern.
It describes that the different independent components of your application should communicate with each other through simple HTTP/HTTPS calls. If an application satisfies this criterion it can be considered as a RESTful web application.
In a RESTful web application, you should utilize the different HTTP verbs for the CRUD operations:
REST is the underlying architectural principle of the web. The main benefit of it is that the client and the server can not know anything about each other. Therefore, you can use any client or server technology, which can send, accept, and can respond to HTTP requests. This is the method that shows how the different microservices can communicate with each other in Spring Cloud, which we will talk about in a later article.
Building a Basic CRUD RESTFul Spring Boot MVC Application
For our example, we will extend the project, which we created here.
We will use Angular.js for the client side. Since this post is not about Angular but about how to utilize Spring Boot and Spring MVC to serve REST requests, we will use an already created source. This is a basic Angular client that showcases a good example for basic CRUD operations by the theme of different shipwrecks. It's written by Dan Bunker, and I already merged its resources to our source code, which I uploaded to a git repository. You can simply clone it from here: spring-boot-demo-project.
In Spring Boot, there are default static content resources where it can natively serve us our content files. These folders automatically added to the project's classpath:
- /static
- /resources
- /public
I created a resources folder under /java/main in our starting application. Hence, we can reach them by simply referencing to them by name in our browser.
If you run the application, you should see the following:
However, if you click on the Shipwrecks link in the header and press F12, you will get the following error in the browser's console:
That's because we didn't set up our backend Spring MVC Controller yet to serve the client API calls.
One import thing I would like to mention before we go towards that is if you would like to change static resources in Spring Boot, you do not need to restart the server. You can try it out pretty easily by updating something in the resources folder without restarting your running application. You will see that the changes apply after you refresh your browser.
Set up Spring MVC REST Controller
What we have done so far, and you can see in your browser, is the orange Client side from above. To communicate with the backend server through HTTP/HTTPS calls, we should build our REST API in our application. Fortunately, we can achieve it quite easily since Spring Boot provides the REST functionality via the Spring MVC dependency. It is the entry point in and out of our server for our web client. Hence, we can write our REST endpoints simply and rapidly.
To continue, make sure your application is running as intended projected above.
Each endpoint follows the standard RESTful best practices by association with an HTTP verb with a URL to handle requests. With these, we can achieve different resources needs, such as adding, viewing, deleting, etc.
Let's create our Controller:
@RestController
@RequestMapping("api/v1/")
public class ShipwreckController {
@RequestMapping(value = "shipwrecks", method = RequestMethod.GET)
public List<Shipwreck> list(){
return ShipwreckStub.list();
}
@RequestMapping(value = "shipwrecks", method = RequestMethod.POST)
public Shipwreck create(@RequestBody Shipwreck shipwreck){
return ShipwreckStub.create(shipwreck);
}
@RequestMapping(value = "shipwrecks/{id}", method = RequestMethod.GET)
public Shipwreck get(@PathVariable Long id){
return ShipwreckStub.get(id);
}
@RequestMapping(value = "shipwrecks/{id}", method = RequestMethod.PUT)
public Shipwreck update(@PathVariable Long id, @RequestBody Shipwreck shipwreck){
return ShipwreckStub.update(id, shipwreck);
}
@RequestMapping(value = "shipwrecks/{id}", method = RequestMethod.DELETE)
public Shipwreck delete(@PathVariable Long id){
return ShipwreckStub.delete(id);
}
}
Here important to use this request mapping: @RequestMapping("api/v1/"), because of our client reference to this path. This gives the base URL for all of our endpoints in our class.
The @RequestMapping value gives our endpoint name and the method says that this endpoint receives only GET HTTP requests.
Our Shipwreck model:
package springboot.my_first_application.model;
public class Shipwreck {
Long id;
String name;
String description;
String condition;
Integer depth;
Double latitude;
Double longitude;
Integer yearDiscovered;
public Shipwreck() { }
public Shipwreck(Long id, String name, String description, String condition, Integer depth, Double latitude, Double longitude, Integer yearDiscovered) {
this.id = id;
this.name = name;
this.description = description;
this.condition = condition;
this.depth = depth;
this.latitude = latitude;
this.longitude = longitude;
this.yearDiscovered = yearDiscovered;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public Integer getDepth() {
return depth;
}
public void setDepth(Integer depth) {
this.depth = depth;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
public Integer getYearDiscovered() {
return yearDiscovered;
}
public void setYearDiscovered(Integer yearDiscovered) {
this.yearDiscovered = yearDiscovered;
}
}
Because we don't have any database connection yet, we should mock our data through a Stub class. We wrote it as below:
public class ShipwreckStub {
private static Map<Long, Shipwreck> wrecks = new HashMap<Long, Shipwreck>();
private static Long idIndex = 3L;
static {
Shipwreck a = new Shipwreck(1L, "U869", "A very deep German UBoat", "FAIR", 200, 44.12, 138.44, 1994);
wrecks.put(1L, a);
Shipwreck b = new Shipwreck(2L, "Thistlegorm", "British merchant boat in the Red Sea", "GOOD", 80, 44.12, 138.44, 1994);
wrecks.put(2L, b);
Shipwreck c = new Shipwreck(3L, "S.S. Yongala", "A luxury passenger ship wrecked on the great barrier reef", "FAIR", 50, 44.12, 138.44, 1994);
wrecks.put(3L, c);
}
public static List<Shipwreck> list() {
return new ArrayList<Shipwreck>(wrecks.values());
}
public static Shipwreck create(Shipwreck wreck) {
idIndex += idIndex;
wreck.setId(idIndex);
wrecks.put(idIndex, wreck);
return wreck;
}
public static Shipwreck get(Long id) {
return wrecks.get(id);
}
public static Shipwreck update(Long id, Shipwreck wreck) {
wrecks.put(id, wreck);
return wreck;
}
public static Shipwreck delete(Long id) {
return wrecks.remove(id);
}
}
Our final project structure:
Now, if you restart the application and click on the same Shipwreck item in the header, you should see the stubbed shipwreck list.
Here we are. If you check the different actions, they should work as well.
Spring MVC Integration Overview
Let's talk about how Spring Boot integrated Spring MVC by adding spring-boot-starter-web to our pom.xml.
It is more about what is included in the appropriate jar file to our classpath. Because we had @SpringBootApplication annotation, which contains @EnableAutoConfiguration, it automatically set up the MVC features for us as well:
- Sets up us ViewResolves: (Determines how to respond based on different content type.) Since we are dealing with JSON payloads, it will set up the Jackosn JSON library to handle the content negotiation for our application JSON types.
- Sets up static resource serving: Spring configured and told Spring MVC that is should serve out static resources that are located at the root of the classpath in the already mentioned paths above.
- Sets up HttpMessageConverter: To convert JSON object into Java ones and vice versa. The basic String encoding is set to UTF-8.
Summary
In this article, we successfully plugged in a front-end client to our basic Spring Boot application and created RESTful endpoints that Angular can successfully talk to through Spring MVC in our Spring Boot app.
Did you already try out Spring MVC and Angular.JS? Let me know in the comments section.
Published at DZone with permission of Zoltan Raffai, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments