0Pricing
TypeScript Academy · บทเรียน

การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง

สร้าง API การสืบค้นที่ต่อคำสั่งได้และตรวจสอบตัวเอง

การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

การออกแบบ Query DSL แบบต่อเนื่อง

เราออกแบบ Query DSL ที่ต่อการเรียกได้ โดยแต่ละขั้นตอนจะ ปรับให้ขั้นตอนถัดไปที่อนุญาตแคบลง ผ่านชนิดที่คืนกลับมา ผลลัพธ์อ่านได้คล้ายภาษาคำสั่งฐานข้อมูล และปฏิเสธลำดับที่ไม่ถูกต้องขณะคอมไพล์

ไวยากรณ์เป้าหมาย

เราต้องการลำดับดังนี้: from ตามด้วย where ที่เป็นตัวเลือกและเรียกซ้ำได้ จากนั้นจบด้วย select คุณไม่สามารถใช้ select ก่อน from และไม่สามารถใช้ from ซ้ำสองครั้ง

อินเทอร์เฟซสถานะ

จำลองแต่ละขั้นตอนเป็นอินเทอร์เฟซที่คืนค่าขั้นตอนถัดไป

interface Builder {
  from(table: string): FromStage;
}
interface FromStage {
  where(cond: string): FromStage; // repeatable
  select(...cols: string[]): Result;
}
interface Result { sql: string; }

การบังคับใช้ลำดับ

เนื่องจาก select มีอยู่เฉพาะบน FromStage การเรียกใช้กับ Builder เริ่มต้นจึงเป็นข้อผิดพลาดขณะคอมไพล์ ลำดับถูกบังคับใช้เพียงจากเมธอดที่แต่ละขั้นตอนเปิดให้ใช้

declare const db: Builder;
db.from("users").select("id"); // ok
db.select("id");               // Error: select missing on Builder

การติดตามคอลัมน์ที่เลือก

เพิ่มเจเนอริกเสมือนเพื่อจดจำคอลัมน์ที่เลือกไว้ ทำให้ชนิดผลลัพธ์มีความแม่นยำ

interface FromStage<T extends string = never> {
  where(c: string): FromStage<T>;
  select<C extends string>(...cols: C[]): Result<C>;
}
interface Result<C extends string> { columns: C[]; }

การปรับละเอียดในการเรียกแต่ละครั้ง

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

const q = db.from("users").where("age > 18").where("active = true");
// still FromStage; select remains available

การป้องกันการใช้ from ซ้ำ

เนื่องจาก FromStage ไม่เปิดให้ใช้ from คุณจึงไม่สามารถเรียกใช้ซ้ำสองครั้งได้ ไวยากรณ์จะห้ามไว้ในเชิงโครงสร้าง จึงไม่จำเป็นต้องมีตัวป้องกันขณะทำงาน

db.from("a").from("b"); // Error: from does not exist on FromStage

ขั้นตอนสิ้นสุด

select คืนค่า Result ซึ่งไม่เปิดให้ใช้ทั้ง where และ from จึงทำให้สายการเรียกสิ้นสุดลง เหลือเพียงการดำเนินการอ่านผลลัพธ์

const r = db.from("users").select("id", "name");
r.columns; // ("id" | "name")[]
// r.where(...) -> Error: where not on Result

ข้อจำกัดคอลัมน์แบบมีชนิด

จำกัดคอลัมน์ให้ตรงกับแบบแผนของตารางที่รู้จักด้วยเจเนอริกอีกตัวหนึ่ง ทำให้คอลัมน์ที่ไม่รู้จักถูกปฏิเสธ และเชื่อม DSL นี้เข้ากับแนวคิดโออาร์เอ็มก่อนหน้า

interface Table<Cols extends string> {
  select<C extends Cols>(...cols: C[]): Result<C>;
}
// db.from gives Table<"id" | "name" | "age">

ขั้นตอนที่เป็นตัวเลือกกับขั้นตอนที่จำเป็น

ทำให้ขั้นตอนหนึ่งจำเป็นโดยเปิดให้ใช้เฉพาะเมธอดถัดไปหลังจากผ่านขั้นตอนนั้นแล้ว ตัวอย่างเช่น บังคับให้มี where อย่างน้อยหนึ่งครั้งด้วยการคืนค่าขั้นตอนที่มี select ปรากฏเฉพาะหลังจากเรียก where แล้ว ชนิดต่อเนื่องแบบเดียวกันนี้ยังสามารถอนุมาน ชนิดแถวผลลัพธ์ จากการดำเนินการคำสั่งสืบค้นได้ด้วย ทำให้ไวยากรณ์ขณะคอมไพล์เชื่อมโยงกับข้อมูลขณะทำงาน

เหตุใดเรื่องนี้จึงสำคัญ

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

ตรวจสอบอย่างรวดเร็ว

ยืนยันความเข้าใจเกี่ยวกับการออกแบบ DSL แบบต่อเนื่อง

สรุปทบทวน

คุณออกแบบ Query DSL แบบต่อเนื่องให้เป็น เครื่องจักรสถานะระดับชนิด โดยอินเทอร์เฟซของแต่ละขั้นตอนจะคืนค่าขั้นตอนถัดไปและเปิดให้ใช้เฉพาะเมธอดที่ถูกต้อง เจเนอริกเสมือนใช้ติดตามคอลัมน์ที่เลือก ขั้นตอนสิ้นสุดใช้จบสายการเรียก และข้อจำกัดคอลัมน์ใช้ปฏิเสธชื่อที่ไม่รู้จัก ทั้งหมดนี้บังคับใช้ผ่านชนิดที่คืนกลับมา

คำถามที่พบบ่อย

บทเรียน “การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง”

สร้าง API การสืบค้นที่ต่อคำสั่งได้และตรวจสอบตัวเอง คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. DSL ระดับชนิดข้อมูลคืออะไร
  2. การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง
  3. การตรวจสอบ input เวลาคอมไพล์
  4. ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล
← กลับไปที่ TypeScript Academy