{"id":34,"date":"2017-04-22T17:24:18","date_gmt":"2017-04-22T17:24:18","guid":{"rendered":"http:\/\/canchito-dev.com\/public\/blog\/?p=34"},"modified":"2021-05-02T13:50:22","modified_gmt":"2021-05-02T13:50:22","slug":"build-a-rest-api-with-spring","status":"publish","type":"post","link":"http:\/\/www.canchito-dev.com\/public\/blog\/2017\/04\/22\/build-a-rest-api-with-spring\/","title":{"rendered":"Build a REST API with Spring"},"content":{"rendered":"<p style=\"text-align: justify;\"><div class=\"perfect-pullquote vcard pullquote-align-full pullquote-border-placement-left\" style=\"font-size:14px !important;\"><blockquote><p style=\"font-size:14px !important;\">In this guide, you will learn how to set up and build a simple REST API with Spring, that provides CRUD operations for entries that are saved into a database. In addition, you will learn how to map HTTP request to specific URL and its response codes, and how to handle unmapped requests.<\/p><\/blockquote><\/div><\/p>\n<div>\n  <a class=\"donate-with-crypto\"\n     href=\"https:\/\/commerce.coinbase.com\/checkout\/faf64f90-2e80-46ee-aeba-0fde14cbeb46\"><br \/>\n    Buy Me a Coffee<br \/>\n  <\/a><br \/>\n  <script src=\"https:\/\/commerce.coinbase.com\/v1\/checkout.js?version=201807\">\n  <\/script>\n<\/div>\n\n<h1 style=\"text-align: justify;\">Contribute Code<\/h1>\n<p style=\"text-align: justify;\">If you would like to become an active contributor to this project please follow theses simple steps:<\/p>\n<ol>\n<li style=\"text-align: justify;\">Fork it<\/li>\n<li style=\"text-align: justify;\">Create your feature branch<\/li>\n<li style=\"text-align: justify;\">Commit your changes<\/li>\n<li style=\"text-align: justify;\">Push to the branch<\/li>\n<li style=\"text-align: justify;\">Create new Pull Request<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><strong>Source code<\/strong> can be downloaded from <a href=\"https:\/\/github.com\/canchito-dev\/build-a-rest-api-with-spring\" target=\"_blank\" rel=\"noopener noreferrer\">github<\/a>.<\/p>\n<h1 class=\"sect1\" style=\"text-align: justify;\">What you\u2019ll need<\/h1>\n<ul style=\"text-align: justify;\">\n<li>About 30\u00a0minutes<\/li>\n<li>A favorite IDE or\u00a0Spring Tool Suite&#x2122; already install<\/li>\n<li><a href=\"http:\/\/www.oracle.com\/technetwork\/java\/javase\/downloads\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">JDK 6<\/a> or later<\/li>\n<\/ul>\n<h1 style=\"text-align: justify;\">Introduction<\/h1>\n<p style=\"text-align: justify;\">As an example, we will be creating a service that accepts HTTP GET, POST, PUT and DELETE requests for performing basic CRUD operations on contacts.\u00a0The requirements of our REST API are:<\/p>\n<ul style=\"text-align: justify;\">\n<li>A <strong><em>POST<\/em> <\/strong>request send to\u00a0<code>http:\/\/localhost:8080\/contact\/<\/code>\u00a0must create a new contact entry in the database by using the information found from the request body and return a 200 response code on success as well as the information of the created contact entry including the unique <em>id<\/em> in the response body.<\/li>\n<li>A <strong><em>DELETE<\/em> <\/strong>request send to\u00a0<code>http:\/\/localhost:8080\/contact\/{id}<\/code> must delete the contact entry referenced by the <em>id<\/em> is found from the URL and return a 200 response code on success or 404 if the requested contact id was not found.<\/li>\n<li>A <strong><em>GET<\/em> <\/strong>request send to\u00a0<code>http:\/\/localhost:8080\/contact\/<\/code>\u00a0must return a 200 response code on success as well as all contact entries that are found in the database.<\/li>\n<li>A <strong><em>GET<\/em> <\/strong>request send to <code>http:\/\/localhost:8080\/contact\/{id}<\/code> must return a 200 response code on success as well as\u00a0the information of the contact entry whose <em>id<\/em> is found from the URL and return a 200 response code on success or 404 if the requested contact id was not found.<\/li>\n<li>A <strong><em>PUT<\/em> <\/strong>request send to<code> http:\/\/localhost:8080\/contact\/{id}<\/code> must update the information of an existing contact entry by using the information found from the request body and return a 200 response code on success as well as the information of the updated contact entry or 404 if the requested contact <em>id<\/em> was not found.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">In order to achieve this, we will follow these steps:<\/p>\n<ol style=\"text-align: justify;\">\n<li>Add the needed dependencies.<\/li>\n<li>Create the entity that contains the information of a single contact entry.<\/li>\n<li>Create the repository interface with methods supporting reading, updating, deleting and creating contacts against a H2 database.<\/li>\n<li>Create the service layer that is responsible of mapping contacts into domain objects and vice versa.<\/li>\n<li>Create the controller class that processes HTTP requests and returns the correct response back to the client.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">Spring Boot does not require any specific code layout to work, however,\u00a0it is\u00a0recommend that you locate your main application class in a root package above other classes. Here is the layout we will be using:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-linenumbers=\"false\" data-enlighter-theme=\"enlighter\">com\r\n +- canchitodev\r\n     +- example\r\n         +- DemoprojectApplication.java\r\n         |\r\n         +- domain\r\n         |   +- Contact.java\r\n         |\r\n         +- exception\r\n         |   +- ConflictException.java\r\n         |   +- ContentNotSupportedException.java\r\n         |   +- ErrorInformation.java\r\n         |   +- ForbiddenException.java\r\n         |   +- GlobalExceptionHandler.java\r\n         |   +- ObjectNotFoundException.java\r\n         |\r\n         +- repository\r\n         |   +- ContactRepository.java\r\n         |\r\n         +- service\r\n         |   +- ContactService.java\r\n         |\r\n         +- controller\r\n             +- ContactrController.java<\/pre>\n<p style=\"text-align: justify;\">So let&#8217;s get started!<\/p>\n<h1 style=\"text-align: justify;\">Getting Started<\/h1>\n<p style=\"text-align: justify;\">This tutorial assumes you can create a project with the help of Spring Initializr or Spring Tool Suite&#x2122;. If you have not, please follow the steps from this post\u00a0<a href=\"http:\/\/canchito-dev\/blog\/2017\/04\/16\/build-a-project-with-spring-initializer-or-spring-tool-suite\/\" target=\"_blank\" rel=\"noopener noreferrer\">Build a project with Spring Initializr or Spring Tool Suite&#x2122;<\/a>\u00a0and include the following dependencies: Web, JPA and H2.<\/p>\n<p style=\"text-align: justify;\">On the other hand, if you already have an empty project, you can just add the needed dependencies by modifying the <code>pom.xml<\/code> file as follow:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"classic\">&lt;dependencies&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;\/artifactId&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;com.h2database&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;h2&lt;\/artifactId&gt;\r\n    &lt;scope&gt;runtime&lt;\/scope&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n  &lt;\/dependency&gt;\r\n&lt;\/dependencies&gt;<\/pre>\n<p style=\"text-align: justify;\">\u00a0Allow me to give a brief description of what each dependency does:<\/p>\n<ul style=\"text-align: justify;\">\n<li style=\"text-align: justify;\"><strong>spring-boot-starter-data-jpa:<\/strong>\u00a0Uses\u00a0data access technologies with enhanced support for JPA based data access layers.<\/li>\n<li style=\"text-align: justify;\"><strong>spring-boot-starter-web:<\/strong>\u00a0Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container<\/li>\n<li style=\"text-align: justify;\"><strong>h2:<\/strong> H2 database engine. Creates an in memory database.<\/li>\n<li style=\"text-align: justify;\"><strong>spring-boot-starter-test:<\/strong>\u00a0Starter for testing Spring Boot applications with libraries including JUnit, Hamcrest and Mockito.<\/li>\n<\/ul>\n<h1 style=\"text-align: justify;\">Creating the Entity Class<\/h1>\n<p style=\"text-align: justify;\">An entity is a representation of a database register. In our case, it is a class representing a contact. Let&#8217;s define the contact class under the domain package.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-theme=\"classic\">package com.canchitodev.example.domain;\r\n\r\nimport javax.persistence.Column;\r\nimport javax.persistence.Entity;\r\nimport javax.persistence.GeneratedValue;\r\nimport javax.persistence.GenerationType;\r\nimport javax.persistence.Id;\r\n\r\nimport org.hibernate.validator.constraints.Email;\r\n\r\n@Entity\r\npublic class Contact {\r\n  \r\n  @Id\r\n  @GeneratedValue(strategy = GenerationType.AUTO)\r\n  @Column(name = \"uuid\", unique = true, nullable = false, length = 255)\r\n  private Long uuid;\r\n  \r\n  @Column(name = \"first_name\", nullable = false, length = 60)\r\n  private String firstName;\r\n  \r\n  @Column(name = \"last_name\", nullable = false, length = 60)\r\n  private String lastName;\r\n  \r\n  @Column(name = \"telephone\", nullable = false, length = 60)\r\n  private String telephone;\r\n  \r\n  @Email\r\n  @Column(name = \"mail\", nullable = false, length = 60)\r\n  private String mail;\r\n  \r\n  public Contact() {}\r\n\r\n  public Contact(Long uuid, String firstName, String lastName, String telephone, String mail) {\r\n    this.uuid = uuid;\r\n    this.firstName = firstName;\r\n    this.lastName = lastName;\r\n    this.telephone = telephone;\r\n    this.mail = mail;\r\n  }\r\n  \r\n  \/\/Getters and setters removed for simplicity\r\n\r\n  @Override\r\n  public String toString() {\r\n    return \"Contact [uuid=\" + uuid + \", firstName=\" + firstName + \", lastName=\" + lastName + \", telephone=\" + telephone\r\n        + \", mail=\" + mail + \"]\";\r\n  }\r\n}<\/pre>\n<p style=\"text-align: justify;\">Here you have a <code>Contact\u00a0<\/code>class with five attributes, the <code>uuid<\/code>, the <code>firstName<\/code>, the <code>lastName, the <\/code><code>telephone<\/code>, and the <code>mail<\/code>. You also have two constructors. The default constructor only exists because it is needed by\u00a0JPA. \u00a0The other constructor is the one you\u2019ll use to create instances of <code>Contact<\/code>\u00a0to be saved to the database.<\/p>\n<p style=\"text-align: justify;\">The <code>@Entity<\/code> annotation specifies that this class is a JPA entity. And since there is no <code>@Table<\/code> annotation, JPA assumes that it is mapped to a table called <code>Contact<\/code>.<\/p>\n<p style=\"text-align: justify;\">The property <code>uuid<\/code> is annotated with the <code>@Id<\/code>\u00a0so that JPA will recognize it as the object\u2019s ID. In addition, the annotation <code>@GeneratedValue<\/code> tell JPA that this property should be automatically generated following the strategy indicated by <code>GenerationType.AUTO<\/code>.<\/p>\n<p style=\"text-align: justify;\">The rest of the properties are annotated with <code>@Column<\/code>, which means that they are mapped to a column with the name specified by name. <code>@Column<\/code>&#8216;s other properties just indicate that the value cannot be null and its max length.<\/p>\n<p style=\"text-align: justify;\">Finally, you can also see the <code>@Email<\/code> annotation. This validates that the column must be a valid e-mail address.<\/p>\n<h1 style=\"text-align: justify;\">Creating the Repository Class<\/h1>\n<p style=\"text-align: justify;\">The repository is an interface which allows CRUD operations on an entity.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"classic\">package com.canchitodev.example.repository;\r\n\r\nimport org.springframework.data.jpa.repository.JpaRepository;\r\nimport org.springframework.data.jpa.repository.JpaSpecificationExecutor;\r\nimport org.springframework.stereotype.Repository;\r\n\r\nimport com.canchitodev.example.domain.Contact;\r\n\r\n@Repository\r\npublic interface ContactRepository extends JpaRepository&lt;Contact, Long&gt;, JpaSpecificationExecutor&lt;Contact&gt; {\r\n\r\n}<\/pre>\n<p style=\"text-align: justify;\">As you can see, we are extending the interface with\u00a0<code>JpaRepository<\/code>. By doing this, we inherit several methods which will allow us to work with <code>Contact<\/code> persistence, including methods for saving, deleting, updating and finding entities. Moreover, we also extend it with\u00a0<code>JpaSpecificationExecutor<\/code>. Thanks to this, we will also be able to searches based on query criteria. For now, just keep in mind, that we will be able to do some basic operations on entities, just by extending it with <code>JpaRepository<\/code>.<\/p>\n<h1 style=\"text-align: justify;\">Creating the Service Class<\/h1>\n<p style=\"text-align: justify;\">In the service class, you will write all your logic. Once you have added your required validations and data manipulations, you call the repository. Note that this class is not required, as this could be done in the controller class. However, in my opinion it it good practice to separate the logic from the controller. Mainly because you can use the service in other parts of your application.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"classic\">package com.canchitodev.example.service;\r\n\r\nimport java.util.List;\r\n\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.stereotype.Service;\r\nimport org.springframework.transaction.annotation.Transactional;\r\n\r\nimport com.canchitodev.example.domain.Contact;\r\nimport com.canchitodev.example.repository.ContactRepository;\r\n\r\n@Service\r\n@Transactional\r\npublic class ContactService {\r\n  \r\n  @Autowired\r\n  private ContactRepository contactRepository;\r\n  \r\n  public Contact findById(Long uuid) {\r\n    Contact contact = this.contactRepository.findOne(uuid);\r\n    return contact;\r\n  }\r\n  \r\n  public List&lt;Contact&gt; findAll() {\r\n    return this.contactRepository.findAll();\r\n  }\r\n  \r\n  public void save(Contact contact) {\r\n    this.contactRepository.save(contact);\r\n  }\r\n\r\n  public void update(Contact contact) {\r\n    Contact entity = this.findById(contact.getUuid());\r\n    \r\n    if(contact.getLastName() == null)\r\n      contact.setLastName(entity.getLastName());\r\n    if(contact.getMail() == null)\r\n      contact.setMail(entity.getMail());\r\n    if(contact.getFirstName() == null)\r\n      contact.setFirstName(entity.getFirstName());\r\n    if(contact.getTelephone() == null)\r\n      contact.setTelephone(entity.getTelephone());\r\n    \r\n    this.save(contact);\r\n  }\r\n  \r\n  public void delete(Long uuid) {\r\n    Contact contact = this.findById(uuid);\r\n    this.contactRepository.delete(contact);\r\n  }\r\n}<\/pre>\n<p style=\"text-align: justify;\">The <code>@Service<\/code> annotation\u00a0allows for implementation classes to be autodetected through classpath scanning. Meanwhile, the <code>@Transactional<\/code> annotation describes transaction attributes on a method or class.<\/p>\n<p style=\"text-align: justify;\">You might find it curious that in the <code>update()<\/code> method, we are sending a <code>Contact<\/code> as an argument. this is because as you will see when we implement the controller class, the request body is automatically mapped to a <code>Contact<\/code> object, but the fields that are not to be updated are null in this object. As a consequence, we need to get the already stored <code>Contact<\/code>, and merge the new information with the one already stored, before saving it.<\/p>\n<h1 style=\"text-align: justify;\">Creating the Controller Class<\/h1>\n<p style=\"text-align: justify;\">A controller is the entry point from where all the HTTP request are handled.\u00a0These components are easily identified by the <code>@RestController<\/code> annotation.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"classic\">package com.canchitodev.example.controller;\r\n\r\nimport java.util.List;\r\n\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.http.HttpEntity;\r\nimport org.springframework.http.HttpStatus;\r\nimport org.springframework.http.MediaType;\r\nimport org.springframework.http.ResponseEntity;\r\nimport org.springframework.web.bind.annotation.PathVariable;\r\nimport org.springframework.web.bind.annotation.RequestBody;\r\nimport org.springframework.web.bind.annotation.RequestMapping;\r\nimport org.springframework.web.bind.annotation.RequestMethod;\r\nimport org.springframework.web.bind.annotation.ResponseBody;\r\nimport org.springframework.web.bind.annotation.RestController;\r\n\r\nimport com.canchitodev.example.domain.Contact;\r\nimport com.canchitodev.example.service.ContactService;\r\n\r\n@RestController\r\n@RequestMapping(\"\/contact\")\r\npublic class ContactController {\r\n  \r\n  @Autowired\r\n  private ContactService contactService;\r\n  \r\n  @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)\r\n  public ResponseEntity&lt;List&lt;Contact&gt;&gt; findAll() {\r\n    List&lt;Contact&gt; contacts = this.contactService.findAll();\r\n    return new ResponseEntity&lt;List&lt;Contact&gt;&gt;(contacts, HttpStatus.OK);\r\n  }\r\n  \r\n  @RequestMapping(value=\"\/{contactId}\", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)\r\n  public ResponseEntity&lt;Contact&gt; findOne(@PathVariable Long contactId) {\r\n    Contact contact = this.contactService.findById(contactId);\r\n    return new ResponseEntity&lt;Contact&gt;(contact, HttpStatus.OK);\r\n  }\r\n  \r\n  @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)\r\n  public ResponseEntity&lt;Contact&gt; create(@RequestBody Contact contact) {\r\n    this.contactService.save(contact);\r\n    return new ResponseEntity&lt;Contact&gt;(contact, HttpStatus.CREATED);\r\n  }\r\n  \r\n  @RequestMapping(value=\"\/{contactId}\", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)\r\n  public ResponseEntity&lt;Contact&gt; update(@PathVariable Long contactId, @RequestBody Contact contact) {\r\n    contact.setUuid(contactId);\r\n    this.contactService.update(contact);\r\n    return new ResponseEntity&lt;Contact&gt;(contact, HttpStatus.OK);\r\n  }\r\n  \r\n  @SuppressWarnings(\"rawtypes\")\r\n  @RequestMapping(value=\"\/{contactId}\", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)\r\n  public @ResponseBody HttpEntity delete(@PathVariable Long contactId) {\r\n    this.contactService.delete(contactId);\r\n    return new ResponseEntity(HttpStatus.NO_CONTENT);\r\n  }\r\n}<\/pre>\n<p style=\"text-align: justify;\">The <code>@RequestMapping<\/code> annotation specifies the URL which the method is mapped to. For instance, a request to\u00a0<code>http:\/\/localhost:8080\/contact\/<\/code> with a request method <em><strong>GET<\/strong><\/em>, will return all the Contact objects stored in the database.<\/p>\n<h1 style=\"text-align: justify;\">Exception Handling<\/h1>\n<p style=\"text-align: justify;\">There are at least three methods for handling exceptions:<\/p>\n<ol style=\"text-align: justify;\">\n<li style=\"text-align: justify;\">Using HTTP status codes<\/li>\n<li style=\"text-align: justify;\">Using a controller based exception handler<\/li>\n<li style=\"text-align: justify;\">And finally, using a global exception handler<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">We are only going to focus on the third option, the global exception handler, as it applies to all the controllers.\u00a0Any class annotated with <code>@ControllerAdvice<\/code> becomes a controller-advice.<\/p>\n<p style=\"text-align: justify;\">First we need to create a class called <code>ErrorInformation<\/code>. Its solo purpose is to\u00a0return the information about the error that was caught.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"classic\">package com.canchitodev.example.exception;\r\n\r\nimport com.fasterxml.jackson.annotation.JsonInclude;\r\nimport com.fasterxml.jackson.annotation.JsonInclude.Include;\r\n\r\npublic class ErrorInformation {\r\n    private String message;\r\n    private String exception;\r\n\r\n    public ErrorInformation(String message, Exception ex) {\r\n        this.message = message;\r\n        if (ex != null) {\r\n          this.exception = ex.getLocalizedMessage();\r\n        }\r\n    }\r\n\r\n    public String getMessage() {\r\n        return message;\r\n    }\r\n\r\n    public void setMessage(String message) {\r\n        this.message = message;\r\n    }\r\n    \r\n    public void setException(String exception) {\r\n        this.exception = exception;\r\n    }\r\n    \r\n    @JsonInclude(Include.NON_NULL)\r\n    public String getException() {\r\n        return exception;\r\n    }\r\n}<\/pre>\n<p style=\"text-align: justify;\">Here is our global exception handler controller class. Notice the class is annotated with <code>@ControllerAdvice<\/code> annotation. Also methods are annotated with <code>@ExceptionHandler<\/code> annotation.\u00a0Note that we also created the exception classes that are detected by the exception handler.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"classic\">package com.canchitodev.example.exception;\r\n\r\nimport org.springframework.http.HttpStatus;\r\nimport org.springframework.http.converter.HttpMessageConversionException;\r\nimport org.springframework.web.bind.annotation.ControllerAdvice;\r\nimport org.springframework.web.bind.annotation.ExceptionHandler;\r\nimport org.springframework.web.bind.annotation.ResponseBody;\r\nimport org.springframework.web.bind.annotation.ResponseStatus;\r\n\r\n@ControllerAdvice\r\npublic class GlobalExceptionHandler {\r\n  @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) \/\/ 415\r\n  @ExceptionHandler(ContentNotSupportedException.class)\r\n  @ResponseBody\r\n  public ErrorInformation handleNotSupported(ContentNotSupportedException e) {\r\n    return new ErrorInformation(\"Content is not supported\", e);\r\n  }\r\n  \r\n  @ResponseStatus(HttpStatus.CONFLICT) \/\/ 409\r\n  @ExceptionHandler(ConflictException.class)\r\n  @ResponseBody\r\n  public ErrorInformation handleConflict(ConflictException e) {\r\n    return new ErrorInformation(\"Conflict\", e);\r\n  }\r\n  \r\n  @ResponseStatus(HttpStatus.NOT_FOUND)  \/\/ 404\r\n  @ExceptionHandler(ObjectNotFoundException.class)\r\n  @ResponseBody\r\n  public ErrorInformation handleNotFound(ObjectNotFoundException e) {\r\n      return new ErrorInformation(\"Not found\", e);\r\n  }\r\n  \r\n  @ResponseStatus(HttpStatus.FORBIDDEN)  \/\/ 403\r\n  @ExceptionHandler(ForbiddenException.class)\r\n  @ResponseBody\r\n  public ErrorInformation handleForbidden(ForbiddenException e) {\r\n      return new ErrorInformation(\"Forbidden\", e);\r\n  }\r\n  \r\n  @ResponseStatus(HttpStatus.BAD_REQUEST) \/\/ 400\r\n  @ExceptionHandler(IllegalArgumentException.class)\r\n  @ResponseBody\r\n  public ErrorInformation handleIllegal(IllegalArgumentException e) {\r\n    return new ErrorInformation(\"Bad request\", e);\r\n  }\r\n  \r\n  @ResponseStatus(HttpStatus.BAD_REQUEST) \/\/ 400\r\n  @ExceptionHandler(HttpMessageConversionException.class)\r\n  @ResponseBody\r\n  public ErrorInformation handleBadMessageConversion(HttpMessageConversionException e) {\r\n    return new ErrorInformation(\"Bad request\", e);\r\n  }\r\n  \r\n  \/\/ Fall back\r\n  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)  \/\/ 500\r\n  @ExceptionHandler(Exception.class)\r\n  @ResponseBody\r\n  public ErrorInformation handleOtherException(Exception e) {\r\n    return new ErrorInformation(\"Internal server error\", e);\r\n  }\r\n}<\/pre>\n<p style=\"text-align: justify;\">Finally, we can modify the service class to throw exceptions when necessary, as these exceptions will be caught be our global exception handler and return the respective status code and message body.<\/p>\n\n<h1 style=\"text-align: justify;\">Summary<\/h1>\n<p style=\"text-align: justify;\">In this guide, you will learned the following:<\/p>\n<ul style=\"text-align: justify;\">\n<li style=\"text-align: justify;\">How to set up and build a simple REST API with Spring.<\/li>\n<li style=\"text-align: justify;\">CRUD operations for entries that are saved into a database.<\/li>\n<li style=\"text-align: justify;\">How to map HTTP request to specific URL and its response codes.<\/li>\n<li style=\"text-align: justify;\">How to handle unmapped requests.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Hope you did enjoy it. And please, if you have any question, doubt or comment, do not hesitate and write us.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you will learn how to set up and build a simple REST API with Spring, that provides CRUD operations for entries that are saved into a database. In addition, you will learn how to map HTTP request to specific URL and its response codes, and how to handle unmapped requests.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[15,3],"tags":[16,6,13,17,11,5],"class_list":["post-34","post","type-post","status-publish","format-standard","hentry","category-rest","category-spring","tag-api","tag-framework","tag-java","tag-jpa","tag-rest","tag-spring"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p8EwXo-y","jetpack-related-posts":[{"id":237,"url":"http:\/\/www.canchito-dev.com\/public\/blog\/2018\/05\/30\/rest-api-with-spring-jpa-criteria\/","url_meta":{"origin":34,"position":0},"title":"REST API with Spring JPA Criteria","author":"canchitodev","date":"May 30, 2018","format":false,"excerpt":"In this guide, you will learn how to set up and build a simple REST API with Spring, that provides CRUD operations for entries that are saved into a database. In addition, you will learn how use JPA's criteria API to perform filtered searches for records.","rel":"","context":"In &quot;JPA&quot;","block_context":{"text":"JPA","link":"http:\/\/www.canchito-dev.com\/public\/blog\/category\/jpa\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2018\/05\/rest-api-with-spring-jpa-criteria-table.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2018\/05\/rest-api-with-spring-jpa-criteria-table.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2018\/05\/rest-api-with-spring-jpa-criteria-table.png?resize=525%2C300 1.5x"},"classes":[]},{"id":477,"url":"http:\/\/www.canchito-dev.com\/public\/blog\/2020\/06\/27\/use-flowable-apps-with-a-custom-rest-api\/","url_meta":{"origin":34,"position":1},"title":"Use Flowable Apps with a Custom REST API","author":"canchitodev","date":"June 27, 2020","format":false,"excerpt":"In this post, you will learn how configure Flowable's apps to use your custom Spring Boot REST API as a backend engine. All this, in a dockerized environment.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"http:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Process engine deployments in Flowable Admin","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/process-engine-deployments.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/process-engine-deployments.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/process-engine-deployments.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/process-engine-deployments.png?resize=700%2C400 2x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/process-engine-deployments.png?resize=1050%2C600 3x"},"classes":[]},{"id":27,"url":"http:\/\/www.canchito-dev.com\/public\/blog\/2017\/04\/30\/integrate-activiti-bpm-with-spring\/","url_meta":{"origin":34,"position":2},"title":"Integrate Activiti BPM with Spring","author":"canchitodev","date":"April 30, 2017","format":false,"excerpt":"In this post, you will learn how to integrate Activiti's engine and REST API into your Spring application. At the same time, you will be able to adapt the Process Engine to your needs by modifying the database connection and the Async Job Executor.","rel":"","context":"In &quot;Activiti BPM&quot;","block_context":{"text":"Activiti BPM","link":"http:\/\/www.canchito-dev.com\/public\/blog\/category\/activiti-bpm\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":263,"url":"http:\/\/www.canchito-dev.com\/public\/blog\/2018\/06\/11\/spring-boot-actuator-production-ready-features\/","url_meta":{"origin":34,"position":3},"title":"Spring Boot Actuator &#8211; Production-ready features","author":"canchitodev","date":"June 11, 2018","format":false,"excerpt":"In this post, we\u2019re going to introduce Spring Boot Actuator, by first covering the basics. Afterwards,\u00a0you will create a Spring project and learn how to use, configure and extend this monitoring tool.","rel":"","context":"In &quot;Actuator&quot;","block_context":{"text":"Actuator","link":"http:\/\/www.canchito-dev.com\/public\/blog\/category\/actuator\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":356,"url":"http:\/\/www.canchito-dev.com\/public\/blog\/2019\/07\/05\/run-flowable-bpm-using-docker-and-mysql\/","url_meta":{"origin":34,"position":4},"title":"Run Flowable BPM using Docker and MySQL","author":"canchitodev","date":"July 5, 2019","format":false,"excerpt":"In this article, you will learn how to compile Flowable source code using MySQL as database source, and generate valid Docker images. Once you have the images, we will use Docker Compose for defining and running a multi-container Docker applications.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"http:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":370,"url":"http:\/\/www.canchito-dev.com\/public\/blog\/2020\/05\/12\/integrate-flowable-into-your-spring-boot-application\/","url_meta":{"origin":34,"position":5},"title":"Integrate Flowable into your Spring Boot Application","author":"canchitodev","date":"May 12, 2020","format":false,"excerpt":"In\u00a0this\u00a0tutorial,\u00a0we\u00a0will\u00a0be\u00a0integrating\u00a0Flowable's\u00a0BPM\u00a0engine\u00a0into\u00a0our\u00a0Spring\u00a0Boot\u00a0application.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"http:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Flowable Test Start Process","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/start_process.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/start_process.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/start_process.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/start_process.png?resize=700%2C400 2x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/start_process.png?resize=1050%2C600 3x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/start_process.png?resize=1400%2C800 4x"},"classes":[]}],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/34","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/comments?post=34"}],"version-history":[{"count":16,"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions"}],"predecessor-version":[{"id":554,"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions\/554"}],"wp:attachment":[{"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/media?parent=34"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/categories?post=34"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/tags?post=34"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}