สร้าง Reactive RESTful Web Service ต่อ PostgreSQL ด้วย R2DBC

Phayao Boonon
3 min readMar 1, 2020

--

หลายคนพัฒนา Reactive RESTful web service ด้วย Spring WebFlux จำเป็นต้องเลือกใช้ NonSQL database เพราะว่ารองรับ Reactive ไม่สามารถใช้งาน Relational Database อย่าง MySQL หรือ PostgreSQL ได้ แต่ตอนนี้ เราสามารถใช้ R2DBC เป็น ตัวเชื่อมระหว่าง Reactive API กับ Relational DB ได้แล้ว ในบทความนี้จะมาลองใช้งาน R2DBC เชื่อมต่อกับ PostgreSQL อย่างง่ายๆ ดูว่าใช้อย่างไร

R2DBC

ย่อมาจาก Reactive Relational Database Connectivity ซึ่งเป็นตัวเชื่อมต่อระหว่าง Reactive Programming APIs และ Relational Database โดยใช้ Reactive Streams spec รองรับ fully-reactive non-blocking API และรองรับ blocking อย่าง JDBC ซึ่งสามารถทำงานได้กับ SQL Database ได้หลากหลาย และทำให้เปลี่ยนจากโมเดล “one thread per connection” ไปเป็นระบบที่สามารถ scale ได้

เมื่อก่อนเป็น Experiment dependency ของ Spring framework อยู่ แต่ตอนนี้ได้พัฒนาเสร็จสมบูรณ์แล้วและ release มาพร้อม Spring Boot 2.3.0

สามารถศึกษาเพิ่มเติมเกี่ยวกับความสามารถของ R2DBC ได้ที่ https://r2dbc.io/

Create Project

สร้าง Spring Boot project ด้วย start.spring.io โดยเลือก dependency เป็น Spring Reactive Web, Spring Data R2DBC, PostgreSQL Driver และ Lombok ซึ่งในบทความนี้สร้างเป็น maven project

  • Spring Reactive Web — เป็น Spring WebFlux สำหรับสร้าง RESTful Web Service
  • Spring Data R2DBC — เป็นตัว R2DBC สำหรับเชื่อมต่อกับ Relational DB
  • PostgreSQL Driver — เป็น PostgreSQL driver ใช้ติดต่อ PostgreSQL server
  • Lombok — เป็น library ที่ช่วยให้เราลด boilerplate code ต่างๆ

เมื่อเราใช้ IDE อย่าง IntelliJ หรือ Eclipse ก็แก้ไขใน pom.xml นิดหน่อย โดยลบ scope ของ dependency j2dbc-postgresql เพราะว่าเราจะต้องใช้บาง class ในนี้สร้าง configuration สำหรับติดต่อกับ PostgreSQL database ให้เหลือแค่นี้

<dependencies>
.....

<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
</dependency>
.....
</dependencies>

Create PostgreSQL Config

เนื่องจากจะต้องเชื่อมต่อกับ PostgreSQL DB ดังนั้นเราจะต้องสร้าง configuration ที่ระบุข้อมูลต่างๆ เกี่ยวกับการเชื่อมต่อ สามารถทำได้ 2 วิธี คือ config ใน applicaiton config หรือ java configuration

application.properties (configuration properties)
PostgresConfig.java (java configuration)

ซึ่งในบทความนี้จะใช้ PostgreSQL ที่ทำงานบนเครื่อง ดังนั้นข้อมูลเชื่อมต่อต่างๆ ดังนี้ โดยที่ port 5432 เป็น default port ของ PostgreSQL และ Username/ Password ก็ตามที่ตั้งค่าไว้

โดย configuration จะสร้าง bean ของ ConnectionFactory ที่ใช้ PostgresqlConnectionFactory และ PostgresqlConnectoinConfiguration builder สร้างข้อมูลการเชื่อมต่อ ซึ่งเป็น class ใน j2dbc-postgresql

แต่จะเป็นต้องสร้าง table customer ใน database ด้วย SQL statement นี้เสียก่อน หรือไม่ก็บันทึก SQL statement นี้ไว้ในไฟล์ schema.sql ใน resources

DROP TABLE IF EXISTS customer;
CREATE TABLE customer (id SERIAL PRIMARY KEY, first_name VARCHAR(255), last_name VARCHAR(255));

Create RESTful Web Service

ทีนี้เราก็มาสร้าง RESTful Web Service ด้วย Spring WebFlux ง่ายๆ ซึ่งประกอบด้วย Controller, Service และ Repository รวมทั้ง Customer data model ที่เป็น class data model ง่ายๆ ประกอบด้วย id , firstName และ lastName

Customer Data Model
CustomerController
Customer REST Controller
CustomerService
Customer Service
CustomerRepository
Customer Spring Data Repository

ใน Repository method สามารถใช้ @Query annotation เช่นเดียวกับการใช้ Spring Data + JDBC และใช้ SQL statement ทั่วไปได้

Run Application

เมื่อสร้างส่วนต่างๆ เสร็จเรียบร้อยก็ลอง run application ด้วยคำสั่ง mvn spring-boot:run ถ้ารันได้ไม่ error ก็แสดงว่า Web Service เราทำงานได้ในเบื้องต้น

ซึ่งอาจจะทดลองใช้ Postman หรือ command line request ไปที่ endpoint http://localhost:8080/customers เพื่อดูว่ามี error ไหมและควรจะ return เป็น JSON list เปล่าๆ ถ้ามี error แสดงว่ามีปัญหาจากจากเชื่อมต่อของการกำหนดค่าให้กับ Configuration

Test Web Application

ซึ่งในบทความนี้จะมาเขียน Integration test เพื่อทดสอบ RESTful Web Service ที่ใช้ R2DBC ว่าทำงานได้ตรงที่เราต้องการหรือไม่ โดยใช้ SpringBootTest และใช้ WebTestClient เพื่อทดสอบในแต่ละ Test case ของ Controller ที่มีฟังก์ชันของ CRUD operation

ALL Unit Test

สรุป

จากที่ได้ทดลองใช้งาน R2DBC เชื่อมต่อ Relational Database อย่าง PostgreSQL ของ Reactive RESTful Web Service นั้นจะเห็นได้ว่า R2DBC สำหรับ Spring Boot นั้นยังพัฒนาไม่สมบูรณ์เท่าไหร่ เพราะยังไม่รองรับ Query derivation เหมือน Spring Data ตัวอื่นๆ ดังนั้นถ้าจะ query ที่ไม่ใช้ method พื้นฐานก็จำเป็นต้องใช้ @Query มากำหนด SQL query statement เอง แต่โดยรวมแล้วใช้งานได้ดีเลยทีเดียว เหมาะสำหรับคนที่ต้องการใช้ Spring WebFlux กับ Relational DB ที่ legacy system ส่วนใหญ่ใช้กัน

--

--

Phayao Boonon
Phayao Boonon

Written by Phayao Boonon

Software Engineer 👨🏻‍💻 Stay Hungry Stay Foolish

No responses yet