สร้าง Microservice + Elasticsearch ด้วย Spring Boot + Spring Data
Elasticsearch เป็นระบบ search engine ตัวหนึ่งที่ได้รับความนิยมสูงสุด ในบทความนี้จะมาลองทำ CRUD Microservice ที่ใช้ Elasticsearch เป็นฐานข้อมูลด้วย Spring Boot และ Spring Data Elasticsearch
Elasticsearch คืออะไร
เป็น real-time distributed และ open source full-text search และ analytic engine ซึ่งสามารถเข้าถึงด้วย RESTful web service และใช้ schema-free JSON document ในการจัดเก็บข้อมูล เขียนด้วย Java ซึ่งสามารถทำงานได้หลากหลาย platform และทำให้ user เข้าถึงข้อมูลขนาดใหญ่ได้อย่างรวดเร็ว
Spring Data Elasticsearch
เป็น Spring Data ที่รองรับ Elasticsearch โดย integrate เข้ากับ Elasticsearch search engine ซึ่งคุณสมบัติหลักคือจัดการกับ POJO model สำหรับเชื่อมต่อเข้ากับ Eleasticsearch Document และเขียนการเชื่อมต่อฐานข้อมูลในรูปแบบ Repository
โดยสามาถเพิ่ม dependency ของ Spring Data Elasticsearch ดังนี้
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
แต่ถ้าเป็น Spring Boot สามารถเพิ่มด้วย
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
วางแผนกันก่อน (เหมือนเดิม)
CRUD Microservice ที่จะสร้างขึ้นเป็น Microservice ที่เก็บข้อมูลของ Customer ด้วย Elasticsearch ดังนั้น จะมี endpoint ที่ดำเนินการกับ customers resource ภายใต้ prefix path เป็น /api ดังนี้
- GET /api/customers — เรียกดูรายการ Customer ทั้งหมด
- GET /api/customers/{id} — เรียกดู Customer โดย user id
- GET /api/customers?name=xxxx — เรียกดูรายการ Customer ด้วยการค้นหาด้วย name
- POST /api/customers — สร้าง Customer ใหม่
- PUT /api/customers/{id} — แก้ไข Customer โดย user id
- DELETE /api/customers/{id} — ลบ Customer โดย user id
โดยแบบออกเป็น 3 Layer คือ Presentation Layer, Service Layer และ Persistence Layer
Use Case เดียวกับ สร้าง CRUD Microservice ด้วย Spring Boot ทำให้บางหัวข้อจะละการอธิบายในลายละเอียดเพราะเหมือนกัน
ติดตั้งและรัน Elasticsearch
ในบทความนี้จะใช้ Elasticseach ที่ติดตั้งในเครื่อง (สำหรับ docker ขอหาวิธีก่อน) macOS ด้วย brew
ดังนี้
$ brew update
$ brew install elasticsearch
และใช้คำสั่ง elasticsearch
ในการเปิดใช้งาน Elasticsearch
สามารถตรวจสอบได้ว่า Elasticsearch ที่ติดตั้งทำงานได้หรือไม่ โดยไปที่ RESTful ของ Elasticsearch http://localhost:9200
ซึ่งจะมีรายละเอียดของ cluster_name
ซึ่งจะใช้ในตอน application config
โดยค่าตั้งต้นของ Elasticsearch มี 2 port ที่ใช้งานคือ
- 9200 — RESTful web service
- 9300 — Nodes communication
สร้าง Spring Boot Project
สามารถใช้ Spring Initializr ในการสร้างโปรเจ็คโดยเลือก dependency เป็น Web
, Elasticsearch
และ Lombok
สร้าง Customer Data (POJO)
เป็น POJO ที่แทนข้อมูล Customer โดยใช้ @Data เพื่อสร้าง Getter/Setter ให้ และใช้ @Document เพื่อระบุว่าจะให้เป็น document index ชื่อว่า customer และ type article
src/main/java/com/iphayao/demo/customer/Customer.java
โดยกำหนดให้แต่ละ field ของ Customer ใน hash table มีลักษณะดังนี้
- id — ตัวแปรค่า id ชนิดข้อมูล String ซึ่งเป็นค่าที่กำหนดให้อัตโนมัติ
- firstName — ตัวแปร String ที่จะต้องมีค่า
- lastName — ตัวแปร String ที่จะต้องมีค่า
- age — ตัวแปร Integer ที่จะต้องมีค่า
- email — ตัวแปร String ที่จะต้องมีรูปแบบเป็น email
สร้าง Customer Controller
เป็น controller ที่ mapping กับ request ต่างๆ ด้วย @ResController ใน presentation layer ดังนี้
src/main/java/com/iphayao/demo/customer/CustomerController.java
สร้าง Customer Service
เป็น Service ที่รองรับการ invoke จาก Controller เพื่อทำ Business Logic ต่างๆ โดยเรียกไปยัง Elasticsearch เพื่อใช้ CRUD operation ด้วย CustomerRepository ดังนี้
src/main/java/com/iphayao/demo/customer/CustomerService.java
สร้าง Customer Repository
เป็นส่วนของ Persistence layer แต่สำหรับ Elasticsearch แล้วจะเก็บข้อมูลไว้ใน document ดังนั้น CustomerRepository
จะเป็น interface ที่ extends จาก ElasticsearchRepository
ในตอน runtime เพื่อใช้ CRUD operation ในการกำเนินการกับ Elasticsearch โดยจะเพิ่ม customer findAll method เข้ามาเพื่อจะให้ได้ output เป็น Page ของ Customer
src/main/java/com/iphayao/demo/customer/CustomerRepository.java
ใช้ @EnableElasticsearchRepositories
เพื่อ config คลาสให้เป็น Elasticsearch Repository
ง่ายไหมครับ
สร้าง Application Configuration
กำหนด config ของ application เพื่อกำหนด port และ prefix ของ URI และ config ของ Elasticsearch
src/main/resources/application.yml
ค่าของ config ให้กับ Spring Data Elasticsearch ดังนี้
- cluster-name — ชื่อของ cluster ใน Elasticsearch สามารถตรวจสอบได้จาก Elasticsearch RESTful
http://localhost:9200
- cluster-nodes — ค่าของ host และ port ของ Elasticsearch ซึ่งใช้ host เป็น localhost และ port เป็น 9300 ซึ่งเป็น port สำหรับสื่อสารของ Node
- repositories.enabled — เป็นการระบุให้ใช้งาน Repositories
ซึ่งถ้า config ผิดจะทำให้ไม่สามารถติดต่อกับ Elasticsearch node ได้แล้วะจะ error ในภายหลัง
ทดลองรัน Application
หลังจากที่ได้ implement ทุกอย่างเรียบร้อยแล้ว สำหรับ Elasticsearch ก็รัน Application (Microservice) ด้วยคำสั่ง mvn spring-boot:run
ถ้ารันสำเร็จจะเห็น message Started
และต้องแน่ใจว่า Elasticsearch ทำงานอยู่
ลองสร้าง Customer ด้วย POST method และ body เป็นข้อมูลของ Customer โดย request ไปที่ endpoint http://localhost:9000/api/customers
ด้วย Postman จะเห็นได้ว่า Service response กลับมาเป็นข้อมูลของ Customer โดยที่ id ถูกกำหนดให้เองอัตโนมัตโดย Elasticsearch เป็น hash key ในรูปแบบของ String ดังนี้
สรุป
จากการสร้าง CRUD Microservice ติดต่อกับ Elasticsearch ด้วย Spring Boot และ Spring Data Elasticsearch นั้นทำได้ง่ายมากเพียงแต่เปลี่ยน Repository เป็น Elasticsearch Repository ด้วยการ extends ElasticsearchRepository ที่จะจัดการ inject dependency ให้ตอน runtime แต่ว่าต้องตั้งค่า application configuration ให้ถูกต้องเพราะว่าถ้าไม่ถูกต้องจะทำให้ไม่สามารถ connect กับ Elasticsearch Node ได้และทำให้ error ตอนที่จะ request มาที่ Application แต่ Elasticsearch เหมาะสำหรับการใช้เป็น Search engine แต่เราใช้เป็นฐานข้อมูลอาจจะไม่ไดเป็น Use Case ที่ดีพอสำหรับใช้งาน Elasticsearch