post-image

CRUD đơn giản với RESTful API trong Spring Boot

REST API

Bài viết trước mình đã giới thiệu về RESTful API là gì và những nguyên tắc để thiết kế ra một API tốt. Vậy nên ở bài viết này chúng ta hãy cùng bắt tay vào việc thử viết ra những API đơn giản phục vụ việc thêm, sửa, xóa, hiển thị trong ứng dụng Spring Boot nhé. Bài này mình có sử dụng những kiến thức liên quan đến Enviroment variable , Lombok RESTful API mọi người có thể tìm đọc lại.

Cài đặt thư viện

Mọi người tạo một ứng dụng Spring Boot ở trong IntelIJ hoặc trên https://start.spring.io/

implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web-services' compileOnly 'org.projectlombok:lombok' runtimeOnly 'mysql:mysql-connector-java' annotationProcessor 'org.projectlombok:lombok' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' }
Code language: JavaScript (javascript)

Cấu hình file application.properties

Chúng ta truy cập vào file application.properties được để ở trong resource và chỉnh sửa như sau:

server.port=${port:8080} spring.datasource.url=${JDBC_DATABASE_URL:} spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #Hibernate spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect spring.jpa.properties.hibernate.id.new_generator_mappings = true spring.jpa.properties.hibernate.show.sql = true spring.jpa.properties.hibernate.format_sql = true spring.jpa.generate-ddl=true spring.jpa.properties.hibernate.hb2dll.auto = update logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Code language: PHP (php)

${JDBC_DATABASE_URL:}  mọi người để đường dẫn tới database của mình tại đây và sửa lại username với password để truy cập tới cơ sở dữ liệu của máy mình.

CRUD đơn giản với RESTful API

Chuẩn bị

  • Model: Mọi người tạo class Category có các thuộc tính như sau

Category.java

package com.example.demo.model; import lombok.Data; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity @Data public class Category { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; }
Code language: CSS (css)

Ở đây mình sử dụng GenerationType là Identity để trường id tự tăng trong cơ sở dữ liệu.

  • Repository: Sau khi tạo xong class Category chúng ta tiến hành tạo interface CategoryRepository kế thừa từ interface JPARepository có sẵn của Spring.
package com.example.demo.repository; import com.example.demo.model.Category; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface ICategoryRepository extends JpaRepository<Category, Long> { }
Code language: CSS (css)

Mình sử dụng annotation @Repository để Spring hiểu đây là một Repository và sẽ được quản lý bởi Spring mà không cần phải khai báo @Bean ở config giống như Spring MVC nữa.

  • Service: Chúng ta sẽ tạo Interface GeneralService chứa các thao tác thêm sửa xóa đơn giản và một Interface ICategoryService kế thừa nó cùng với một class CategoryService implement lại.

IGeneralService.java

package com.example.demo.service; import java.util.Optional; public interface IGeneralService<T> { Iterable<T> findAll(); Optional<T> findById(Long id); T save(T t); void remove(Long id); }
Code language: HTML, XML (xml)

ICategoryService.java

package com.example.demo.service; import com.example.demo.model.Category; public interface ICategoryService extends IGeneralService<Category> { }
Code language: CSS (css)

CategoryService.java

package com.example.demo.service; import com.example.demo.model.Category; import com.example.demo.repository.ICategoryRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Optional; @Service public class CategoryService implements ICategoryService { @Autowired private ICategoryRepository categoryRepository; @Override public Iterable<Category> findAll() { return categoryRepository.findAll(); } @Override public Optional<Category> findById(Long id) { return categoryRepository.findById(id); } @Override public Category save(Category category) { return categoryRepository.save(category); } @Override public void remove(Long id) { categoryRepository.deleteById(id); } }
Code language: CSS (css)

Oki vậy là bước chuẩn bị đã xong giờ chúng ta sẽ tiến hành viết các API cho việc thêm sửa xóa và hiển thị một Category

Tạo RestController

Chúng ta tiến hành tạo một CategoryController trong package controller với annotaiton @RestController

package com.example.demo.controller; import com.example.demo.service.ICategoryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @CrossOrigin("*") @RequestMapping("/categories") public class CategoryController { @Autowired private ICategoryService categoryService; }
Code language: CSS (css)

Ở trên mình để @CrossOrigin(“*”) để có thể truy cập từ mọi nơi, sau này mọi người có thể để một đường dẫn cụ thể vào đây để chỉ trang web đó mới có thể lấy được API của dự án và mình dùng @RequestMapping(“/categories”) để thêm tiền tố “/categories” ở trước các API được viết trong controller này

Tạo mới một Category

Chúng ta viết hàm tạo mới một Category với phương thức POST như sau:

@PostMapping public ResponseEntity<Category> createNewCategory(@RequestBody Category category) { return new ResponseEntity<>(categoryService.save(category), HttpStatus.OK); }
Code language: CSS (css)

Lấy ra Category

Sử dụng @GetMapping cho phương thức lấy ra tất cả danh sách Category trong cơ sở dữ liệu và một Category cụ thể.

  • Lấy ra tất cả Category trong cơ sở dữ liệu
@GetMapping public ResponseEntity<Iterable<Category>> getAllCategory() { return new ResponseEntity<>(categoryService.findAll(), HttpStatus.OK); }
Code language: CSS (css)
  • Lấy ra một Category
@GetMapping("/{id}") public ResponseEntity<Category> getCategory(@PathVariable Long id) { Optional<Category> categoryOptional = categoryService.findById(id); return categoryOptional.map(category -> new ResponseEntity<>(category, HttpStatus.OK)) .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); }
Code language: PHP (php)

Cập nhật Category

@PutMapping("/{id}") public ResponseEntity<Category> updateCategory(@PathVariable Long id, @RequestBody Category category) { Optional<Category> categoryOptional = categoryService.findById(id); return categoryOptional.map(category1 -> { category.setId(category1.getId()); return new ResponseEntity<>(categoryService.save(category), HttpStatus.OK); }).orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); }
Code language: PHP (php)

Xóa một Category

@DeleteMapping("/{id}") public ResponseEntity<Category> deleteCategory(@PathVariable Long id) { Optional<Category> categoryOptional = categoryService.findById(id); return categoryOptional.map(category -> { categoryService.remove(id); return new ResponseEntity<>(category, HttpStatus.OK); }).orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); }
Code language: PHP (php)

Kết luận

Vậy ở bài viết này mình đã hướng dẫn mọi người cách viết CRUD API đơn giản với Spring Boot. Hi vọng bài viết có ích với mọi người.

Leave a Reply

Your email address will not be published.