Friday, August 17, 2018

Create a REST API with Spring Boot

In this post, I will explain how to create a simple a REST API with Spring Boot

Spring Boot
Spring Boot is a framework that provides inbuilt configuration that a Java web application can run without the XML configurations that come with a typical Spring application and it does not require a traditional WAR deployment. Spring Boot makes it easy Spring based Applications that you can just run.


REST Endpoints

Our application will expose the following endpoints:

GET /bookstore/book - Retrieves all books
GET /bookstore/book{id}  - Retrieves a specific boo based on ID
POST /bookstore/book  - Creates a new book
PUT /bookstore/book{id}  - Updates an existing book
DELETE /bookstore/book/{id} - Removes a specific book based on ID
DELETE /bookstore/book - Removes all books

Creating SpringBootApplication class

package com.libmgmt.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages={"com.libmgmt"})
public class MySpringBootApplication {

public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}

Creating BookController

package com.libmgmt.model;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;
import com.libmgmt.exception.BookException;
import com.libmgmt.model.Book;
import com.libmgmt.service.BookService;

@RestController
@RequestMapping("/")
public class BookController {

@Autowired
BookService bookService;

@RequestMapping(value = "/book", method = RequestMethod.GET)
public ResponseEntity<List<Book>> findAllBooks() {
List<Book> books = bookService.findAllBooks();
if (books.isEmpty()) {
return new ResponseEntity<List<Book>>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<List<Book>>(books, HttpStatus.OK);
}

@RequestMapping(value = "/book/{id}", method = RequestMethod.GET)
public ResponseEntity<?> findBook(@PathVariable("id") long id) {
Book book = bookService.findById(id);
if (book == null) {
return new ResponseEntity<BookException>(
new BookException("ERROR: Book Id " + id
+ " not found"), HttpStatus.NOT_FOUND);
}
return new ResponseEntity<Book>(book, HttpStatus.OK);
}

@RequestMapping(value = "/book", method = RequestMethod.POST)
public ResponseEntity<?> createBook(@RequestBody Book book,
UriComponentsBuilder ucBuilder) {

if (bookService.isBookExist(book)) {
return new ResponseEntity<BookException>(
new BookException("ERROR: Book name ="
+ book.getName() + " already exist."),
HttpStatus.CONFLICT);
}
bookService.saveBook(book);

HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/api/book/{id}")
.buildAndExpand(book.getId()).toUri());
return new ResponseEntity<String>(headers, HttpStatus.CREATED);
}

@RequestMapping(value = "/book/{id}", method = RequestMethod.PUT)
public ResponseEntity<?> updateBook(@PathVariable("id") long id,
@RequestBody Book book) {

Book currentBook = bookService.findById(id);

if (currentBook == null) {
return new ResponseEntity<BookException>(
new BookException("ERROR: Id =" + id
+ " not found."), HttpStatus.NOT_FOUND);
}

currentBook.setName(book.getName());
currentBook.setAuthor(book.getAuthor());
currentBook.setPrice(book.getPrice());
return new ResponseEntity<Book>(currentBook, HttpStatus.OK);
}

@RequestMapping(value = "/book/{id}", method = RequestMethod.DELETE)
public ResponseEntity<?> deleteBook(@PathVariable("id") long id) {

Book book = bookService.findById(id);
if (book == null) {
return new ResponseEntity<BookException>(
new BookException("ERROR: Id =" + id
+ " not found."), HttpStatus.NOT_FOUND);
}
bookService.deleteBookById(id);
return new ResponseEntity<Book>(HttpStatus.NO_CONTENT);
}

@RequestMapping(value = "/book", method = RequestMethod.DELETE)
public ResponseEntity<Book> deleteAllBooks() {

bookService.deleteAllBooks();
return new ResponseEntity<Book>(HttpStatus.NO_CONTENT);
}

}

Creating Book Model

package com.libmgmt.model;

public class Book {
private long id;
private String name;
private String author;
private float price;

public Book() {
id = 0;
}

public Book(long id, String name, String author, float price) {
this.id = id;
this.name = name;
this.author = author;
this.price = price;
}

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 getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public float getPrice() {
return price;
}

public void setPrice(float price) {
this.price = price;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Book other = (Book) obj;
if (id != other.id)
return false;
return true;
}


}

Creating Book Service 

package com.libmgmt.service;

import java.util.List;
import com.libmgmt.model.Book;

public interface BookService {

public Book findById(long id);
public Book findByName(String bookName);
public void saveBook(Book book);
public void updateBook(Book book);
public void deleteBookById(long id);
public List<Book> findAllBooks();
public void deleteAllBooks();
public boolean isBookExist(Book Book);


}

Creating Book Mock Service Implementation

package com.libmgmt.service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Service;
import com.libmgmt.model.Book;

@Service
public class BookServiceImpl implements BookService {

private static final AtomicLong counter = new AtomicLong();

private static List<Book> books;

static {
init();
}

private static void init() {
List<Book> bookList = new ArrayList<Book>();
bookList.add(new Book(counter.incrementAndGet(), "Java", "Andrew",
100.0f));
bookList.add(new Book(counter.incrementAndGet(),
"Data Structure & Algorithm", "John", 200.f));
books = bookList;
}

public Book findById(long id) {
for (Book book : books) {
if (book.getId() == id) {
return book;
}
}
return null;
}

public void saveBook(Book book) {
book.setId(counter.incrementAndGet());
books.add(book);
}

public void updateBook(Book book) {
int index = books.indexOf(book);
books.set(index, book);
}

public void deleteBookById(long id) {
for (Iterator<Book> iter = books.iterator(); iter.hasNext();) {
Book book = iter.next();
if (book.getId() == id) {
iter.remove();
}
}
}

public List<Book> findAllBooks() {
return books;
}

public void deleteAllBooks() {
books.clear();
}

public boolean isBookExist(Book book) {
return findByName(book.getName()) != null;
}

public Book findByName(String bookName) {
for (Book book : books) {
if (book.getName().equalsIgnoreCase(bookName)) {
return book;
}
}
return null;
}

}

Creating Book Exception 

package com.libmgmt.exception;

public class BookException {
private String errorMessage;

public BookException(String errorMessage) {
this.errorMessage = errorMessage;
}

public String getErrorMessage() {
return errorMessage;
}

}


Book Services Curl

Get All books
curl -X GET -i 'http://127.0.0.1:8080/bookstore/book'

Get Single Book
curl -X GET -i 'http://127.0.0.1:8080/bookstore/book/1'

Create Book
curl -X POST -H 'Content-Type: application/json' -i 'http://127.0.0.1:8080/bookstore/book' --data '{"id":3,"name":"C++","author":"E Balagrusamy","price":100.0}'

Update Book 
curl -X PUT -H 'Content-Type: application/json' -i 'http://127.0.0.1:8080/bookstore/book/3' --data '{"id":3,"name":"C++","author":"E Balagrusamy","price":120.0}'

Delete Single Book
curl -X DELETE -H 'Content-Type: application/json' -i 'http://127.0.0.1:8080/bookstore/book/5'

Delete All Books

curl -X DELETE -H 'Content-Type: application/json' -i 'http://127.0.0.1:8080/bookstore/book/3' --data '{"id":4,"name":"Angular JS","author":"E Balagrusamy","price":120.0}'

1 comment:

  1. Garage door spring replacement should be done regularly in order to avoid accidents. There are two types of garage door springs and be able know how to replace them. Guesthouse booking

    ReplyDelete

Create a REST API with Spring Boot

In this post, I will explain how to create a simple a REST API with Spring Boot Spring Boot Spring Boot is a framework that provides inbuil...