Dalam tutorial ini, kita akan membangun Rest API dengan menggunakan Spring Boot, Spring Data JPA/Hibernate untuk berinteraksi dengan PostgreSQL
Api yang akan kita bangun kali ini adalah CRUD untuk Customer, yaitu berfungsi untuk create, read, update dan delete. Berikut ini katalog API nya
Method | URL | Deskripsi |
POST | /api/customers | Menambah customer baru |
GET | /api/customers | Mengambil semua data customer |
GET | /api/customers/:id | Mengambil data customer berdasarkan :id |
GET | /api/customers?name=[keyword] | Mengambil data customer berdasarkan nama |
PUT | /api/customers/:id | Mengubah data customer berdasarkan :id |
DELETE | /api/customers/:id | Menghapus data customer berdasarkan :id |
Oke, langsung saja kita masuk ke langkah pertama. Seperti biasanya kita mulai dengan menggenerate project dengan Spring Initializr, atur seperti gambar di bawah ini
Klik generate kemudian buka dengan editor favorit anda. Dalam tutorial ini yang dipakai adalah NetBeans IDE.
Buka file pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bittama</groupId>
<artifactId>customer</artifactId>
<version>0.0.1</version>
<name>customer</name>
<description>Customer Service</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Kita pastikan semua dependensi yang dibutuhkan sudah masuk dalam file pom.xml.
Mengatur Koneksi Database
Langkah kedua buat database dengan nama customer. Untuk mengatur koneksi ke database terdapat pada file application.properties
yang terdapat dalam src/main/resources
spring.datasource.url=jdbc:postgresql://localhost:5432/customer
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
Properti spring.datasource.username
dan spring.datasource.password
disesuaikan username dan password PostgrSQL yang akan dihubungkan
spring.jpa.hibernate.ddl-auto
terdapat 4 pilihan yaitu create, create-drop, validate
dan update
Membuat Entity Class Customer.java
Dalam tutorial ini kita menggunakan Lombok. Lombok adalah sebuah library yang berguna untuk mengurangi penulisan kode.
Bagaimana cara menggunakannya? Untuk menggunakan lombok, kita hanya perlu menggunakan anotasi @Getter
dan @Setter
pada Class Customer. Jadi dengan menambah anotasi tersebut kita tidak perlu lagi membuat method getter dan setter nya. Untuk lebih jelasnya bisa dilihat pada kode di bawah ini.
package com.bittama.customer.entities;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
public class Customer implements Serializable {
@Id
private String id;
private String name;
private String address;
private String email;
private String phone;
}
@Getter
dan @Setter
anotasi lombok yang digunakan untuk menggenerate method getter dan setter
@Entity
anotasi yang digunakan untuk mengidentifikasi Entity Class
@Id
anotasi yang digunakan untuk menandai primary key
Membuat Repository Interface
Buat class dalam package com.bittama.repositories
dengan nama CustomerRepository
yang meng extends pada JpaRepository
.
package com.bittama.customer.repositories;
import com.bittama.customer.entities.Customer;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CustomerRepository extends JpaRepository<Customer, String> {
public List<Customer> findByNameContaining(String name);
}
Sekarang kita dapat menggunakan method yang ada dalam CustomerRepository seperti save(), findOne(), findById(), findAll(),
dan lainnya tanpa harus mengimplementasikannya.
Kita juga menambahkan custom method findByNameContaining()
yang digunakan untuk pencarian berdasarkan nama.
Membuat Rest API Controller
Rest API Controller digunakan untuk method create(), read(), update()
dan delete()
agar dapat diakses menggunakan protokol http. Buat sebuah class dengan nama CustomerController
dalam package com.bittama.controllers
seperti di bawah ini
package com.bittama.customer.controllers;
import com.bittama.customer.entities.Customer;
import com.bittama.customer.repositories.CustomerRepository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class CustomerController {
@Autowired
private CustomerRepository customerRepository;
@GetMapping("/customers")
public ResponseEntity<List<Customer>> findAll(
@RequestParam(name = "name",
required = false,
defaultValue = "") String name) {
try {
List<Customer> customers;
if (StringUtils.hasText(name)) {
customers = customerRepository.findByNameContaining(name);
} else {
customers = customerRepository.findAll();
}
if (customers.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(customers, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/customers/{id}")
public ResponseEntity<Customer> findById(
@PathVariable("id") String id) {
Optional<Customer> customerData = customerRepository.findById(id);
if (customerData.isPresent()) {
return new ResponseEntity<>(customerData.get(), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@PostMapping("/customers")
public ResponseEntity<Customer> create(
@RequestBody Customer customer) {
try {
Customer newCustomer = new Customer();
newCustomer.setId(UUID.randomUUID().toString());
newCustomer.setName(customer.getName());
newCustomer.setAddress(customer.getAddress());
newCustomer.setEmail(customer.getEmail());
newCustomer.setPhone(customer.getPhone());
return new ResponseEntity<>(customerRepository.save(newCustomer), HttpStatus.CREATED);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PutMapping("/customers/{id}")
public ResponseEntity<Customer> update(
@PathVariable("id") String id,
@RequestBody Customer customer) {
Optional<Customer> customerData = customerRepository.findById(id);
if (customerData.isPresent()) {
Customer updatedCustomer = customerData.get();
updatedCustomer.setName(customer.getName());
updatedCustomer.setAddress(customer.getAddress());
updatedCustomer.setEmail(customer.getEmail());
updatedCustomer.setPhone(customer.getPhone());
return new ResponseEntity<>(customerRepository.save(updatedCustomer), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@DeleteMapping("/customers/{id}")
public ResponseEntity<HttpStatus> delete(
@PathVariable("id") String id) {
try {
customerRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/customers")
public ResponseEntity<HttpStatus> deleteAll() {
try {
customerRepository.deleteAll();
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
@RestController
merupakan anotasi yang digunakan menandai bahwa class tersebuat adalah controller untuk Rest API
@RequestMapping("/api")
digunakan untuk menandai bahwa url API diawali dengan /api
@Autowired
digunakan untuk meng-inject CustomerRepository
Mari Kita Coba
Untuk mencobanya jalankan perintah mvn spring-boot:run
pada command line atau jika anda menggunakan editor NetBeans tekan tombol F6.
Table customer akan secara otomatis digenerate sesuai dengan Customer Entity Class
Kita test api dengan menggunakan postman
Untuk mengetest api yang lain silakan di coba sendiri.
Source code dapat diunduh di https://github.com/andiksystem/spring-customer. Semoga bermanfaat.