เอกสารในห้องสมุดของฉัน

แถบด้านข้างหลายราก

flex-layout

  • Getting Started

  • Guides

  • Reference

typed-rx-http

  • Getting Started

  • Guides

  • Reference

global-rx-state

  • Getting Started

  • Guides

  • Reference

webflux-fe-dev-assistant

reactive-mongo-dsl

ภาพรวม

อธิบายพื้นฐานและหลักการในการกำจัดปัญหาที่ต้องเขียนสัญญา API และประเภทซ้ำสองครั้งในขณะที่พัฒนาร่วมกับ backend และ frontend, เปลี่ยนงานพัฒนาที่ซ้ำซ้อนให้เป็นการสร้างจาก source.


เรื่องราวต้นกำเนิด

ฉันทำงานร่วมกับ backend และ frontend เมื่อสร้างฟังก์ชันหนึ่ง ฉันต้องเขียน endpoint และ request/response DTO ใน Java WebFlux และจากนั้นต้องเขียน URL และ TypeScript type เดียวกันใน frontend เพื่อให้ตรงกับเอกสาร Swagger ทำให้ต้องย้ายข้อมูลที่มีอยู่ใน backend ไปในรูปแบบอื่นซ้ำแล้วซ้ำอีก

ปัญหาที่ใหญ่ที่สุดคือการเขียน API สัญญาที่สร้างโดย backend ให้เป็นรูปแบบที่ frontend สามารถใช้ได้ หากมีการแก้ไข URL, HTTP method, path/query parameter หรือโครงสร้าง request/response ใด ๆ หนึ่งในสองฝ่ายแตกต่างกัน จะพบปัญหาหลังจากการคอมไพล์ไปแล้ว ปัญหานี้ไม่ใช่แค่เรื่องน่ารำคาญ แต่การที่คนต้องจัดการเนื้อหาเดียวกันสองครั้งทำให้เกิดความไม่ตรงกันที่ใหญ่กว่า

ฉันต้องการลดการทำซ้ำเมื่อสร้าง RouterFunction และ handler หากเพิ่มการอ้างอิงเช่น ApiAccountHandler::search ใน router ฉันคิดว่าควรสร้างโครงสร้างของคลาส handler และ method ที่ไม่มีอยู่โดยอัตโนมัติ การเขียน query MongoDB โดยการทำซ้ำชื่อฟิลด์ entity เป็นสตริงเช่น "username" ก็เป็นเรื่องยุ่งยากและมีโอกาสพิมพ์ผิดได้ง่าย ดังนั้นฉันจึงใส่ฟังก์ชันในการอ่านแหล่งข้อมูล entity เพื่อสร้างเป็น Java enum ไว้ในเครื่องมือเดียวกัน

ดังนั้นการสร้าง Swagger/OpenAPI, การสร้างโครงสร้าง handler และการสร้าง enum ฟิลด์ Mongo entity จึงถูกสร้างขึ้นก่อน และหลังจากนั้นก็เพิ่มการสร้าง AsyncAPI โดยใช้ RSocket แม้ว่าจะดูเหมือนเป็นแนวคิดที่แยกจากกัน แต่จุดเริ่มต้นคือสิ่งเดียวกัน คือไม่ให้คนต้องเขียนข้อมูลที่ได้บันทึกไว้ในแหล่งข้อมูล backend ซ้ำอีกครั้ง และให้เครื่องมือพัฒนาสร้างส่วนที่เครื่องอ่านได้แทน

ปรัชญาการพัฒนา

ใช้แหล่งข้อมูล backend เป็นเกณฑ์

ใช้ข้อมูลที่มีอยู่ใน RouterFunction, handler, DTO และ entity เป็นต้นฉบับสำหรับเอกสาร API และโค้ดที่สร้างขึ้น การไม่จัดการสัญญาเดียวกันในไฟล์แยกต่างหากเป็นสิ่งสำคัญ

เลือกการทำงานอัตโนมัติในช่วงการพัฒนามากกว่าความมหัศจรรย์ในระหว่างการทำงาน

ไม่ใช่ framework ที่ดักจับคำขอใน production แต่จะวิเคราะห์แหล่งข้อมูลในสภาพแวดล้อมการพัฒนาท้องถิ่นและสร้างไฟล์จริง ผลลัพธ์สามารถตรวจสอบด้วยตาและจัดการเวอร์ชันได้

ปฏิบัติตามแนวทางของโครงการอย่างคาดเดาได้

ไม่มุ่งหวังที่จะสร้างคอมไพเลอร์ทั่วไปที่เข้าใจโค้ด Java ทั้งหมด แต่จะมุ่งเน้นไปที่การวิเคราะห์โครงสร้าง endpoint ฟังก์ชัน WebFlux ที่ฉันใช้จริงด้วยกฎที่ชัดเจน

กำจัดช่วงการเชื่อมต่อที่ซ้ำซ้อน

สร้าง Swagger จาก backend endpoint และเชื่อมโยงกระบวนการที่ generator frontend อ่านเอกสารนั้นเพื่อสร้าง service และ type เป็นโซ่การทำงานอัตโนมัติเดียวกัน

อ่านอะไรจากแบ็กเอนด์

แหล่งข้อมูล RouterFunction

อ่าน HTTP method, nested path, handler method reference และ predicate

แหล่งที่มาของ Handler

อ่าน request body, query/path ค่าและ response publisher type

Request / Response DTO

เชื่อมต่อ Java type ที่เขียนไว้แล้วใน backend กับ OpenAPI schema

แหล่งที่มาของ Mongo entity

อ่าน Java field และ storage raw name ของ @Field, @Document collection

RSocket controller

อ่าน @MessageMapping route และ request/response payload type

สร้างอะไรแทนการเขียนซ้ำ

แต่ผมไม่ต้องการให้ typed-rx-http ถูกใช้เฉพาะใน WebFlux เท่านั้น แม้ว่า backend จะไม่สร้าง Swagger โดยตรง แต่หากมี TypeScript ที่ตรงตาม OpenAPI สเปค ก็สามารถลดการเขียน URL สตริงและ request type ด้วยมือได้ RSocket client ก็ถูกสร้างขึ้นตามเหตุผลเดียวกันโดยอิงจากเอกสาร AsyncAPI

สร้าง REST endpoint ให้เป็น API สัญญาที่สามารถใช้ได้กับ front service และ TypeScript type generator

asyncapi-rsocket.json

สร้าง RSocket route และ payload ให้เป็นสัญญาที่ front RSocket client generator สามารถอ่านได้

แหล่งที่มาของ Handler

สร้างและปรับปรุงโครงสร้าง class และ method ตาม handler reference ที่ระบุใน RouterFunction

{Entity}Fields enum

สร้าง enum สำหรับ Java field และ storage raw name ของ entity เพื่อไม่ให้ชื่อ field เป็นสตริงซ้ำกัน

CollectionNames enum

สร้างให้สามารถใช้ชื่อ collection ที่ประกาศใน @Document แทนสตริงได้

กระบวนการอัตโนมัติในโปรเจกต์ปัจจุบัน

เขียน RouterFunction, handler และ Java request/response DTO ใน backend

watcher ของ local profile ตรวจจับการเปลี่ยนแปลง source และอัปเดต swagger.json หรือ asyncapi-rsocket.json

สคริปต์สร้าง @byeolnaerim/typed-rx-http ของ front อ่านเอกสารและสร้างฟังก์ชัน service และ TypeScript type

ในโค้ดหน้าจอไม่ต้องเขียน URL และ response type ใหม่ แต่ใช้ฟังก์ชันที่สร้างขึ้นโดยการ import

เมื่อ entity เปลี่ยนแปลง field enum และ collection enum ที่ใช้ใน query จะถูกอัปเดตด้วย