กําหนดเอนทิตีสําหรับ REST และ GraphQL
เอนทิตีเป็นส่วนประกอบหลักของ Data API Builder แต่ละเอนทิตีแมปกับออบเจ็กต์ฐานข้อมูลและกําหนดลักษณะที่ออบเจ็กต์นั้นปรากฏผ่าน REST และ GraphQL API ของคุณ เมื่อคุณกําหนดเอนทิตีอย่างถูกต้อง คุณจะควบคุมได้ว่าลูกค้าสามารถเข้าถึงข้อมูลใดได้บ้าง
ส่วนนี้ entities สร้างขึ้นจากแฟ้มการกําหนดค่าที่คุณสร้างขึ้น เป็นที่ที่คุณระบุตาราง มุมมอง และวัตถุฐานข้อมูลอื่นๆ ที่ DAB แสดง คุณกําหนดค่าแต่ละเอนทิตีด้วยการแม็ปต้นทาง การกําหนดเองฟิลด์ และข้อกําหนดความสัมพันธ์ที่กําหนดพื้นผิว API ของคุณ
ตัวอย่างทั่วทั้งหน่วยนี้ใช้ตารางฐานข้อมูลตัวอย่างต่อไปนี้ โปรดคํานึงถึงคําจํากัดความเหล่านี้ในขณะที่คุณทํางานผ่านการกําหนดค่าแต่ละรายการ:
CREATE TABLE dbo.Categories (
CategoryID INT PRIMARY KEY,
CategoryName NVARCHAR(50) NOT NULL
);
CREATE TABLE dbo.Products (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(100) NOT NULL,
UnitPrice DECIMAL(10, 2) NOT NULL,
UnitsInStock INT NOT NULL,
CategoryID INT FOREIGN KEY REFERENCES dbo.Categories(CategoryID)
);
แมปออบเจ็กต์ฐานข้อมูลกับเอนทิตี
ข้อกําหนดของเอนทิตีเริ่มต้นด้วยชื่อและการอ้างอิงแหล่งที่มา ชื่อเอนทิตีจะกลายเป็นตัวระบุที่ใช้ในตําแหน่งข้อมูล API และคิวรี GraphQL ในขณะที่แหล่งที่มาชี้ไปยังออบเจ็กต์ฐานข้อมูลจริง
"entities": {
"Product": {
"source": {
"object": "dbo.Products",
"type": "table"
},
"permissions": [
{
"role": "anonymous",
"actions": ["read"]
}
]
}
}
การตั้งค่าคอนฟิกนี้แสดง dbo.Products ตารางเป็น Product เอนทิตี ไคลเอ็นต์ REST เข้าถึงได้ที่ /api/Productในขณะที่ไคลเอ็นต์ GraphQL สืบค้นเป็น product (เอกพจน์) หรือ products (พหูพจน์) DAB จะสร้างแบบแผนการตั้งชื่อเหล่านี้โดยอัตโนมัติตามชื่อเอนทิตีของคุณ
typeคุณสมบัติระบุชนิดออบเจ็กต์ฐานข้อมูล: table, , viewหรือ stored-procedure. แต่ละประเภทมีความสามารถที่แตกต่างกัน ตารางสนับสนุนการดําเนินการ CRUD เต็มรูปแบบ (สร้าง อ่าน อัปเดต ลบ) มุมมองโดยทั่วไปสนับสนุนการดําเนินการอ่าน และกระบวนงานที่เก็บไว้จะเรียกใช้ตรรกะแบบกําหนดเอง
กําหนดค่าการแม็ปฟิลด์และนามแฝง
บางครั้งชื่อคอลัมน์ฐานข้อมูลของคุณไม่ตรงกับแบบแผนการตั้งชื่อที่คุณต้องการใน API ของคุณ การแมปฟิลด์ช่วยให้คุณเปลี่ยนชื่อคอลัมน์และควบคุมฟิลด์ที่จะปรากฏในการตอบกลับ API
"Product": {
"source": {
"object": "dbo.Products",
"type": "table"
},
"mappings": {
"ProductID": "id",
"ProductName": "name",
"UnitPrice": "price",
"UnitsInStock": "stockQuantity"
},
"permissions": [
{
"role": "anonymous",
"actions": ["read"]
}
]
}
ด้วยการแมปเหล่านี้ ไคลเอ็นต์จะเห็น id, name, , priceและ stockQuantity ในการตอบกลับ API แทนชื่อคอลัมน์ฐานข้อมูลเดิม วิธีนี้ช่วยให้คุณนําเสนอ API ที่สะอาดและสอดคล้องกันในขณะที่ยังคงรักษาสคีมาฐานข้อมูลที่มีอยู่ของคุณไว้ไม่เปลี่ยนแปลง
Note
เมื่อคุณใช้การแม็ปฟิลด์ ไคลเอ็นต์ต้องใช้ชื่อที่แม็ปในการสืบค้นและการกลายพันธุ์ ชื่อคอลัมน์ฐานข้อมูลเดิมจะกลายเป็นรายละเอียดการใช้งานภายใน
เปิดใช้งานการแคชเพื่อประสิทธิภาพที่ดีขึ้น
การแคช Data API Builder ช่วยลดภาระฐานข้อมูลโดยการจัดเก็บผลลัพธ์การสืบค้นชั่วคราว คุณสามารถกําหนดค่าการแคชได้ทั้งในระดับส่วนกลาง (ในส่วนรันไทม์) และต่อเอนทิตีสําหรับการควบคุมแบบละเอียด
"Product": {
"source": {
"object": "dbo.Products",
"type": "table"
},
"rest": {
"enabled": true
},
"graphql": {
"enabled": true,
"cache": {
"enabled": true,
"ttl-seconds": 60
}
},
"permissions": [...]
}
ttl-secondsคุณสมบัติ (เวลาที่ใช้งานจริง) จะกําหนดระยะเวลาที่ข้อมูลที่แคชยังคงใช้ได้ สําหรับแค็ตตาล็อกผลิตภัณฑ์ที่มีการเปลี่ยนแปลงไม่บ่อยนัก ระยะเวลาแคชที่นานขึ้นจะช่วยปรับปรุงประสิทธิภาพการทํางาน สําหรับข้อมูลที่เปลี่ยนแปลงอย่างรวดเร็ว เช่น การนับสินค้าคงคลัง ให้ใช้ระยะเวลาที่สั้นลงหรือปิดใช้งานการแคช
การแคชทํางานแตกต่างกันสําหรับ REST และ GraphQL การแคช REST จะพิจารณา URL ที่สมบูรณ์รวมถึงพารามิเตอร์การสืบค้น ในขณะที่การแคช GraphQL จะตรวจสอบโครงสร้างการสืบค้น ทั้งคู่เคารพ TTL ที่คุณกําหนดค่า
ใช้การแบ่งหน้าสําหรับชุดข้อมูลขนาดใหญ่
เมื่อเอนทิตีมีเรกคอร์ดจํานวนมาก การส่งคืนเรกคอร์ดทั้งหมดในการตอบสนองครั้งเดียวจะสร้างปัญหาด้านประสิทธิภาพและการใช้งาน Data API Builder ให้การสนับสนุนการแบ่งหน้าในตัวที่คุณสามารถปรับแต่งได้ตามเอนทิตี
"Product": {
"source": {
"object": "dbo.Products",
"type": "table"
},
"rest": {
"enabled": true,
"path": "/products"
},
"graphql": {
"enabled": true,
"type": {
"singular": "product",
"plural": "products"
}
},
"permissions": [...]
}
ไคลเอ็นต์ REST ใช้พารามิเตอร์คิวรี เช่น $first และ $after เพื่อนําทางผ่านหน้า:
GET /api/products?$first=10
GET /api/products?$first=10&$after=eyJQcm9kdWN0SUQiOjEwfQ==
$afterพารามิเตอร์ประกอบด้วยเคอร์เซอร์ที่ชี้ไปยังรายการสุดท้ายจากหน้าก่อนหน้า DAB จะสร้างเคอร์เซอร์เหล่านี้โดยอัตโนมัติตามคีย์หลักของเอนทิตีของคุณ
ไคลเอ็นต์ GraphQL ใช้การแบ่งหน้าที่คล้ายกันผ่านอาร์กิวเมนต์ first และ after ในคิวรี:
query {
products(first: 10, after: "eyJQcm9kdWN0SUQiOjEwfQ==") {
items {
id
name
price
}
hasNextPage
endCursor
}
}
การตอบกลับประกอบด้วยhasNextPageendCursorและฟิลด์ที่ไคลเอ็นต์ใช้เพื่อตรวจสอบว่ามีข้อมูลเพิ่มเติมหรือไม่และจะดึงข้อมูลได้อย่างไร
กําหนดค่าการกรองและการค้นหา
Data API Builder สร้างความสามารถในการกรองโดยอัตโนมัติตามฟิลด์ของเอนทิตีของคุณ ลูกค้าสามารถกรองผลลัพธ์โดยใช้ตัวดําเนินการเปรียบเทียบมาตรฐาน
สําหรับจุดสิ้นสุด REST การกรองจะใช้ไวยากรณ์แบบสอบถามสไตล์ OData:
GET /api/products?$filter=price gt 100 and stockQuantity gt 0
สําหรับ GraphQL การกรองจะใช้วัตถุอินพุตที่พิมพ์:
query {
products(filter: { price: { gt: 100 }, stockQuantity: { gt: 0 } }) {
items {
id
name
price
}
}
}
DAB สร้างชนิดตัวกรองสําหรับแต่ละฟิลด์ตามชนิดข้อมูล ฟิลด์ตัวเลขรองรับ gt, gte, , lt, lte, eqและ neq. เขตข้อมูลสตริงเพิ่ม contains, startsWith, และendsWith คุณไม่จําเป็นต้องกําหนดค่าความสามารถเหล่านี้อย่างชัดเจน จะพร้อมใช้งานโดยอัตโนมัติสําหรับฟิลด์ที่เปิดเผยทั้งหมด
เคล็ดลับ
สําหรับสถานการณ์การกรองที่ซับซ้อนซึ่งไม่สามารถแสดงผ่านตัวดําเนินการมาตรฐาน ให้พิจารณาสร้างมุมมองหรือกระบวนงานที่เก็บไว้ที่ห่อหุ้มตรรกะการกรอง จากนั้นแสดงเป็นเอนทิตีแยกต่างหาก
กําหนดความสัมพันธ์ของเอนทิตีสําหรับ GraphQL
จุดแข็งของ GraphQL อยู่ที่การสํารวจความสัมพันธ์ระหว่างเอนทิตีในคิวรีเดียว Data API Builder รองรับการกําหนดความสัมพันธ์ที่แมปกับความสัมพันธ์คีย์นอกของฐานข้อมูลของคุณ
"entities": {
"Product": {
"source": { "object": "dbo.Products", "type": "table" },
"relationships": {
"category": {
"cardinality": "one",
"target.entity": "Category",
"source.fields": ["CategoryID"],
"target.fields": ["CategoryID"]
}
},
"permissions": [...]
},
"Category": {
"source": { "object": "dbo.Categories", "type": "table" },
"relationships": {
"products": {
"cardinality": "many",
"target.entity": "Product",
"source.fields": ["CategoryID"],
"target.fields": ["CategoryID"]
}
},
"permissions": [...]
}
}
ด้วยการกําหนดค่าความสัมพันธ์เหล่านี้ ไคลเอ็นต์ GraphQL สามารถสอบถามระหว่างเอนทิตีได้:
query {
products {
items {
name
price
category {
name
}
}
}
}
คุณสมบัติจะ cardinality บ่งชี้ว่าความสัมพันธ์ส่งกลับหนึ่งรายการหรือหลายรายการ ใช้สําหรับ one ความสัมพันธ์แบบกลุ่มต่อหนึ่ง (ผลิตภัณฑ์กับประเภท) และ many สําหรับความสัมพันธ์แบบหนึ่งต่อกลุ่ม (ประเภทกับผลิตภัณฑ์)
ทําความเข้าใจการสร้างปลายทาง REST
เมื่อคุณกําหนดเอนทิตี DAB จะสร้างจุดสิ้นสุด REST โดยอัตโนมัติตามแบบแผนมาตรฐาน แต่ละเอนทิตีจะได้รับเส้นทาง URL พื้นฐาน และคํากริยา HTTP จะแมปกับการดําเนินการ CRUD
สําหรับเอนทิตีที่ตั้งชื่อ Product ด้วยการตั้งค่าคอนฟิกเริ่มต้น:
| วิธีการ HTTP | รูปแบบ URL | การผ่าตัด |
|---|---|---|
| GET | /api/Product |
แสดงรายการผลิตภัณฑ์ทั้งหมด (แบ่งหน้า) |
| GET | /api/Product/id/123 |
รับสินค้าพร้อมรหัส 123 |
| POST | /api/Product |
สร้างผลิตภัณฑ์ใหม่ |
| สำรอง | /api/Product/id/123 |
ปรับปรุงหรือสร้างผลิตภัณฑ์ 123 |
| แก้ไข | /api/Product/id/123 |
ปรับปรุงผลิตภัณฑ์บางส่วน 123 |
| DELETE | /api/Product/id/123 |
ลบสินค้า 123 |
/id/กลุ่มใน URL บ่งชี้ถึงการค้นหาคีย์หลัก สําหรับคีย์คอมโพสิต ให้เชื่อมโยงเซ็กเมนต์คีย์หลายเซ็กเมนต์: /api/OrderDetail/orderId/100/productId/50.
ปรับแต่งเส้นทางปลายทาง REST
คุณสามารถปรับเปลี่ยนรูปแบบ URL เริ่มต้นผ่านการกําหนดค่าเอนทิตี ส่วนนี้ rest ควบคุมลักษณะการทํางานเฉพาะของ REST:
"Product": {
"source": { "object": "dbo.Products", "type": "table" },
"rest": {
"enabled": true,
"path": "/products",
"methods": {
"get": true,
"post": true,
"put": false,
"patch": true,
"delete": true
}
},
"permissions": [...]
}
พร็อพเพอร์ตี้pathจะเปลี่ยน URL จาก /api/Product เป็น/api/products การตั้งค่านี้มีประโยชน์เมื่อคุณต้องการชื่อปลายทางที่เป็นตัวพิมพ์เล็กและพหูพจน์ที่แตกต่างจากชื่อเอนทิตีของคุณ
ออบเจ็กต์ช่วยให้คุณสามารถ methods เปิดหรือปิดใช้งานคํากริยา HTTP ที่เฉพาะเจาะจงได้ ในตัวอย่าง PUT นี้ ถูกปิดใช้งาน ซึ่งจะป้องกันการแทนที่ระเบียนทั้งหมดในขณะที่ยังคงอนุญาตให้ PATCH มีการปรับปรุงบางส่วน รูปแบบการกําหนดค่านี้ป้องกันการสูญหายของข้อมูลโดยไม่ได้ตั้งใจจากไคลเอ็นต์ที่อาจส่งเรกคอร์ดที่ไม่สมบูรณ์
เคล็ดลับ
วิธีการปิดใช้งานในระดับปลายทางให้การป้องกันในเชิงลึก แม้ว่าสิทธิ์จะอนุญาตให้ดําเนินการได้ แต่การปิดใช้งานวิธีการจะป้องกันไม่ให้ดําเนินการทั้งหมด
ตั้งค่าการกําหนดค่าตําแหน่งข้อมูล GraphQL
GraphQL ทํางานผ่านปลายทางเดียว ซึ่งโดยทั่วไปจะอยู่ที่ /graphql. คิวรี การกลายพันธุ์ และการสมัครใช้งานทั้งหมดจะผ่านจุดสิ้นสุดนี้ โดยมีเนื้อหาคําขอระบุการดําเนินการ
"runtime": {
"graphql": {
"enabled": true,
"path": "/graphql",
"allow-introspection": true,
"depth-limit": 8,
"multiple-mutations": {
"create": { "enabled": true }
}
}
}
allow-introspectionการตั้งค่าจะควบคุมว่าไคลเอ็นต์สามารถสืบค้น Schema GraphQL ได้หรือไม่ ในระหว่างการพัฒนา การวิปัสสนาจะช่วยให้เครื่องมือต่างๆ เช่น GraphiQL และ Apollo Studio เข้าใจ API ของคุณ ในการผลิต ให้พิจารณาปิดใช้งานเพื่อซ่อนรายละเอียดการใช้งาน
การตั้งค่านี้ depth-limit ช่วยป้องกันการสืบค้นที่ซ้อนกันที่ซับซ้อนเกินไปซึ่งอาจทําให้ฐานข้อมูลของคุณตึงเครียด ความลึก 8 ช่วยให้สามารถข้ามความสัมพันธ์ได้อย่างสมเหตุสมผลในขณะที่บล็อกการละเมิดที่อาจเกิดขึ้นผ่านการสืบค้นที่ซ้อนกันอย่างลึกซึ้ง
กําหนดการตั้งค่าเอนทิตีเฉพาะ GraphQL
แต่ละเอนทิตีสามารถมีการกําหนดค่าเฉพาะ GraphQL ที่แตกต่างจาก REST:
"Product": {
"source": { "object": "dbo.Products", "type": "table" },
"graphql": {
"enabled": true,
"type": {
"singular": "product",
"plural": "products"
},
"operation": "query"
},
"rest": {
"enabled": true
},
"permissions": [...]
}
คุณสมบัติจะ type กําหนดชื่อชนิด GraphQL เอง โดยค่าเริ่มต้น DAB จะใช้ชื่อเอนทิตี แต่คุณสามารถระบุรูปแบบเอกพจน์และพหูพจน์ที่แตกต่างกันได้
คุณสมบัติจะ operation กําหนดตําแหน่งที่การกลายพันธุ์ปรากฏ ใช้สําหรับ query เอนทิตีแบบอ่านอย่างเดียว (เช่น มุมมอง) หรือ mutation สําหรับเอนทิตีที่สนับสนุนการดําเนินการเขียน