สร้าง Microservice + Elasticsearch ด้วย Spring Boot + Spring Data

Phayao Boonon
4 min readOct 7, 2018

--

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

อ้างอิง

--

--

Phayao Boonon
Phayao Boonon

Written by Phayao Boonon

Software Engineer 👨🏻‍💻 Stay Hungry Stay Foolish

No responses yet