แนวคิดไม่ตรงกันระหว่าง DDD Application Services และ REST API


20

ฉันกำลังพยายามออกแบบแอปพลิเคชันที่มีโดเมนธุรกิจที่ซับซ้อนและข้อกำหนดเพื่อสนับสนุน REST API (ไม่ใช่ REST อย่างเคร่งครัด แต่มุ่งเน้นไปที่ทรัพยากร) ฉันมีปัญหาบางอย่างในการหาวิธีเปิดเผยโมเดลโดเมนในลักษณะที่เน้นทรัพยากร

ใน DDD ลูกค้าของโมเดลโดเมนจำเป็นต้องผ่านเลเยอร์ 'Application Services' ขั้นตอนเพื่อเข้าถึงฟังก์ชันการทำงานทางธุรกิจใด ๆ ที่ใช้งานโดย Entities และ Domain Services ตัวอย่างเช่นมีแอปพลิเคชันบริการที่มีสองวิธีในการอัปเดตเอนทิตีผู้ใช้:

userService.ChangeName(name);
userService.ChangeEmail(email);

API ของ Application Service นี้แสดงคำสั่ง (คำกริยาขั้นตอน) ไม่ใช่สถานะ

แต่ถ้าเราต้องจัดหา RESTful API สำหรับแอปพลิเคชันเดียวกันนั่นก็คือโมเดลทรัพยากรของผู้ใช้ซึ่งมีลักษณะดังนี้:

{
name:"name",
email:"email@mail.com"
}

API ของทรัพยากรที่มุ่งเน้น exposes รัฐไม่ได้คำสั่ง สิ่งนี้ทำให้เกิดข้อกังวลต่อไปนี้:

  • การดำเนินการอัปเดตแต่ละครั้งกับ REST API สามารถแมปกับการเรียกขั้นตอนบริการแอปพลิเคชันอย่างน้อยหนึ่งรายการขึ้นอยู่กับคุณสมบัติที่จะถูกอัพเดตบนโมเดลรีซอร์ส

  • การดำเนินการอัปเดตแต่ละครั้งจะดูเหมือน atomic ไปยังไคลเอนต์ REST API แต่ไม่ได้ดำเนินการเช่นนั้น การเรียกใช้บริการแอปพลิเคชันแต่ละครั้งได้รับการออกแบบเป็นธุรกรรมแยกต่างหาก การอัพเดตหนึ่งฟิลด์ในโมเดลรีซอร์สสามารถเปลี่ยนกฎการตรวจสอบสำหรับฟิลด์อื่น ดังนั้นเราจำเป็นต้องตรวจสอบความถูกต้องของเขตข้อมูลโมเดลทรัพยากรทั้งหมดด้วยกันเพื่อให้แน่ใจว่าการเรียกใช้บริการแอปพลิเคชันทั้งหมดนั้นถูกต้องก่อนที่จะเริ่มสร้าง การตรวจสอบความถูกต้องของชุดคำสั่งพร้อมกันนั้นมีความสำคัญน้อยกว่าการทำทีละครั้ง เราจะทำเช่นนั้นกับลูกค้าที่ไม่ทราบว่ามีคำสั่งแต่ละรายการได้อย่างไร

  • การเรียกใช้เมธอดบริการแอปพลิเคชันในลำดับที่ต่างกันอาจมีผลกระทบที่แตกต่างกันในขณะที่ REST API ทำให้ดูเหมือนไม่มีความแตกต่าง (ภายในทรัพยากรเดียว)

ฉันสามารถคิดประเด็นที่คล้ายกันขึ้นมาได้ แต่โดยพื้นฐานแล้วสิ่งเหล่านี้ล้วนเกิดจากสิ่งเดียวกัน หลังจากการเรียกใช้บริการแอปพลิเคชันแต่ละครั้งสถานะของระบบจะเปลี่ยนไป กฎของการเปลี่ยนแปลงที่ถูกต้องคืออะไรชุดของการกระทำที่เอนทิตีสามารถทำการเปลี่ยนแปลงต่อไปได้ API ที่มุ่งเน้นทรัพยากรพยายามทำให้ดูเหมือนเป็นปฏิบัติการแบบอะตอมมิกทั้งหมด แต่ความซับซ้อนของการข้ามช่องว่างนี้ต้องไปที่ใดที่หนึ่งและมันดูใหญ่มาก

นอกจากนี้หาก UI มีการมุ่งเน้นคำสั่งมากกว่าซึ่งมักเป็นกรณีนี้เราจะต้องแมประหว่างคำสั่งและทรัพยากรในฝั่งไคลเอ็นต์และจากนั้นกลับมาที่ฝั่ง API

คำถาม:

  1. ความซับซ้อนทั้งหมดนี้ควรได้รับการจัดการโดยเลเยอร์การทำแผนที่ REST-to-AppService (หนา) หรือไม่
  2. หรือฉันขาดอะไรบางอย่างที่ฉันเข้าใจใน DDD / REST?
  3. REST สามารถใช้งานได้จริงหรือไม่สำหรับการแสดงการทำงานของแบบจำลองโดเมนในระดับที่ค่อนข้างซับซ้อน (ค่อนข้างต่ำ)

3
ฉันไม่คิดว่า REST นั้นจำเป็น อย่างไรก็ตามเป็นไปได้ที่ shoehorn DDD เป็นมัน: infoq.com/articles/rest-api-on-cqrs programmers.stackexchange.com/questions/242884/… blog.42.nl/articles/rest-andddd-incompatible
ระหว่าง

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

2
@astr คำตอบง่ายๆคือทรัพยากรไม่ใช่แบบของคุณดังนั้นการออกแบบรหัสการจัดการทรัพยากรไม่ควรส่งผลกระทบต่อการออกแบบโมเดลของคุณ ทรัพยากรเป็นลักษณะภายนอกของระบบโดยที่โมเดลอยู่ภายใน คิดถึงทรัพยากรในแบบเดียวกับที่คุณอาจนึกถึง UI ผู้ใช้อาจคลิกปุ่มเดียวบน UI และสิ่งต่าง ๆ เกิดขึ้นในแบบจำลอง คล้ายกับทรัพยากร ลูกค้าอัพเดททรัพยากร (คำสั่ง PUT เดียว) และอาจมีสิ่งต่าง ๆ นับล้านเกิดขึ้นในตัวแบบ มันเป็นการต่อต้านรูปแบบที่จะจับคู่แบบจำลองของคุณเข้ากับแหล่งข้อมูล
Cormac Mulhall

1
นี่เป็นการพูดคุยที่ดีเกี่ยวกับการดำเนินการในโดเมนของคุณเนื่องจากผลข้างเคียงของการเปลี่ยนแปลงสถานะ REST ทำให้โดเมนและเว็บของคุณแยกจากกัน (กรอไปข้างหน้าอย่างรวดเร็วถึง 25 นาทีสำหรับบิตฉ่ำ) yow.eventer.com/events/1004/talks/1047
Cormac Mulhall

1
ฉันยังไม่แน่ใจเกี่ยวกับสิ่งที่ "ผู้ใช้ทั้งหมดเป็นหุ่นยนต์ / เครื่องรัฐ" ฉันคิดว่าเราควรพยายามทำให้ส่วนต่อประสานผู้ใช้ของเราดูเป็นธรรมชาติยิ่งกว่านั้น ...
guillaume31

คำตอบ:


10

ฉันมีปัญหาเดียวกันและ "แก้ไข" โดยการสร้างแบบจำลองทรัพยากร REST แตกต่างกันเช่น:

/users/1  (contains basic user attributes) 
/users/1/email 
/users/1/activation 
/users/1/address

ดังนั้นฉันจึงแบ่งทรัพยากรที่มีขนาดใหญ่และซับซ้อนออกเป็นหลาย ๆ แต่ละกลุ่มมีกลุ่มของแอตทริบิวต์ดั้งเดิมที่ค่อนข้างเหนียวแน่นซึ่งคาดว่าจะนำมาประมวลผลร่วมกัน

แต่ละการดำเนินการเกี่ยวกับทรัพยากรเหล่านี้คืออะตอมแม้ว่ามันอาจจะดำเนินการโดยใช้วิธีการบริการต่าง ๆ - อย่างน้อยใน Spring / Java EE มันไม่ได้เป็นปัญหาในการสร้างการทำธุรกรรมที่มีขนาดใหญ่ขึ้นจากวิธีการต่างๆ การขยายพันธุ์) คุณมักจะต้องทำการตรวจสอบเพิ่มเติมสำหรับทรัพยากรพิเศษนี้ แต่ก็ยังสามารถจัดการได้ค่อนข้างเนื่องจากแอตทริบิวต์ (ควรจะ) เหนียว

นี่เป็นวิธีที่ดีสำหรับวิธี HATEOAS เนื่องจากทรัพยากรที่ละเอียดยิ่งขึ้นของคุณนำเสนอข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่คุณสามารถทำได้ (แทนที่จะมีตรรกะนี้บนไคลเอนต์และเซิร์ฟเวอร์เนื่องจากไม่สามารถแสดงได้อย่างง่ายดายในทรัพยากร)

มันไม่สมบูรณ์แบบแน่นอน - ถ้า UIs ไม่ได้จำลองด้วยทรัพยากรเหล่านี้ (โดยเฉพาะ UIs ที่เน้นข้อมูล) ก็สามารถสร้างปัญหาได้เช่น UI แสดงรูปแบบขนาดใหญ่ของคุณลักษณะทั้งหมดของทรัพยากรที่กำหนด (และทรัพยากรย่อย) และช่วยให้คุณ แก้ไขทั้งหมดและบันทึกในคราวเดียว - นี่เป็นการสร้างภาพลวงตาของอะตอมมิกแม้ว่าลูกค้าจะต้องเรียกการดำเนินการทรัพยากรหลายอย่าง (ซึ่งเป็นอะตอมมิกเอง แต่ลำดับทั้งหมดไม่ใช่อะตอมมิก)

นอกจากนี้การแบ่งทรัพยากรนี้บางครั้งก็ไม่ง่ายหรือชัดเจน ฉันทำสิ่งนี้เป็นส่วนใหญ่เกี่ยวกับทรัพยากรที่มีพฤติกรรมที่ซับซ้อน / วงจรชีวิตเพื่อจัดการความซับซ้อนของมัน


นั่นคือสิ่งที่ฉันคิดเช่นกัน - สร้างตัวแทนทรัพยากรที่ละเอียดมากขึ้นเพราะสะดวกในการเขียน คุณจะจัดการกับการสืบค้นทรัพยากรได้อย่างไรเมื่อมีความละเอียดมาก? สร้างการนำเสนอแบบ de-normalized แบบอ่านอย่างเดียวด้วยหรือไม่
astreltsov

1
ไม่ฉันไม่มีการรับรองมาตรฐานแบบอ่านอย่างเดียว ฉันใช้มาตรฐานjsonapi.orgและมีกลไกในการรวมแหล่งข้อมูลที่เกี่ยวข้องในการตอบกลับสำหรับทรัพยากรที่กำหนด โดยทั่วไปฉันพูดว่า "ให้ฉันผู้ใช้ที่มี ID 1 และรวมถึงอีเมลและแหล่งข้อมูลย่อยของการเปิดใช้งาน" สิ่งนี้จะช่วยในการกำจัดการเรียกใช้ REST พิเศษสำหรับแหล่งข้อมูลย่อยและจะไม่ส่งผลกระทบต่อความซับซ้อนของไคลเอนต์ในการจัดการกับแหล่งย่อยหากคุณใช้ไลบรารีไคลเอ็นต์ JSON API ที่ดี
qbd

ดังนั้นคำขอ GET เดียวบนเซิร์ฟเวอร์จึงแปลเป็นคำค้นหาจริงหนึ่งรายการขึ้นไป (ขึ้นอยู่กับจำนวนทรัพยากรย่อยที่รวมอยู่) ซึ่งจะรวมกันเป็นวัตถุทรัพยากรเดียวหรือไม่
astreltsov

เกิดอะไรขึ้นถ้าจำเป็นต้องทำรังมากกว่าหนึ่งระดับ
astreltsov

ใช่ในฐานข้อมูลเชิงสัมพันธ์นี้อาจแปลเป็นหลายแบบสอบถาม JSON API สามารถสร้างรังตามอำเภอใจได้อธิบายไว้ที่นี่: jsonapi.org/format/#fetching-includes
qbd

0

ปัญหาสำคัญของที่นี่คือตรรกะทางธุรกิจถูกเรียกอย่างโปร่งใสเมื่อมีการเรียกใช้ REST อย่างไร นี่เป็นปัญหาที่ไม่ได้รับการจัดการโดยตรงจาก REST

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

จากตัวอย่างข้างต้นเราสามารถเรียกใช้เมธอดตรรกะทางธุรกิจที่เรียกว่า validateName เมื่อฟิลด์ชื่อถูกเปลี่ยนโดยใช้ REST:

class User { 
      String name;
      String email;

      /**
       * This method will be transparently invoked when the value of name is changed
       * by REST.
       * The XorUpdate annotation becomes effective for PUT/POST actions
       */
      @XorPostChange
      public void validateName() {
        if(name == null) {
          throw new IllegalStateException("Name cannot be set as null");
        }
      }
    }

ด้วยเครื่องมือดังกล่าวที่คุณสามารถใช้งานได้สิ่งที่คุณต้องทำคือใส่คำอธิบายประกอบวิธีการใช้ตรรกะทางธุรกิจของคุณอย่างเหมาะสม


0

ฉันมีปัญหาบางอย่างในการหาวิธีเปิดเผยโมเดลโดเมนในลักษณะที่เน้นทรัพยากร

คุณไม่ควรเปิดเผยแบบจำลองโดเมนในลักษณะเชิงทรัพยากร คุณควรเปิดเผยแอปพลิเคชันในลักษณะที่เน้นทรัพยากร

หาก UI นั้นเน้นที่คำสั่งมากกว่าซึ่งมักจะเป็นกรณีนั้นเราจะต้องแมประหว่างคำสั่งและทรัพยากรในฝั่งไคลเอ็นต์แล้วกลับไปที่ฝั่ง API

ไม่เลย - ส่งคำสั่งไปยังแหล่งข้อมูลแอปพลิเคชันที่เชื่อมต่อกับรูปแบบโดเมน

การดำเนินการอัปเดตแต่ละครั้งกับ REST API สามารถแมปกับการเรียกขั้นตอนบริการแอปพลิเคชันอย่างน้อยหนึ่งรายการขึ้นอยู่กับคุณสมบัติที่จะถูกอัพเดตบนโมเดลรีซอร์ส

ใช่แม้ว่าจะมีวิธีการสะกดที่แตกต่างกันเล็กน้อยซึ่งอาจทำให้สิ่งต่าง ๆ ง่ายขึ้น; การดำเนินการอัพเดตแต่ละครั้งเทียบกับ REST api แม็พกับกระบวนการที่ส่งคำสั่งไปยังการรวมหนึ่งรายการขึ้นไป

การดำเนินการอัปเดตแต่ละครั้งจะดูเหมือน atomic ไปยังไคลเอนต์ REST API แต่ไม่ได้ดำเนินการเช่นนั้น การเรียกใช้บริการแอปพลิเคชันแต่ละครั้งได้รับการออกแบบเป็นธุรกรรมแยกต่างหาก การอัพเดตหนึ่งฟิลด์ในโมเดลรีซอร์สสามารถเปลี่ยนกฎการตรวจสอบสำหรับฟิลด์อื่น ดังนั้นเราจำเป็นต้องตรวจสอบความถูกต้องของเขตข้อมูลโมเดลทรัพยากรทั้งหมดด้วยกันเพื่อให้แน่ใจว่าการเรียกใช้บริการแอปพลิเคชันทั้งหมดนั้นถูกต้องก่อนที่จะเริ่มสร้าง การตรวจสอบความถูกต้องของชุดคำสั่งพร้อมกันนั้นมีความสำคัญน้อยกว่าการทำทีละครั้ง เราจะทำเช่นนั้นกับลูกค้าที่ไม่ทราบว่ามีคำสั่งแต่ละรายการได้อย่างไร

คุณกำลังไล่ล่าหางที่ผิดที่นี่

ลองนึกภาพ: นำ REST ออกจากภาพโดยสมบูรณ์ ลองจินตนาการว่าคุณกำลังเขียนส่วนต่อประสานเดสก์ท็อปสำหรับแอปพลิเคชันนี้แทน ลองจินตนาการอีกครั้งว่าคุณมีความต้องการด้านการออกแบบที่ดีจริงๆและกำลังใช้งาน UI แบบอิงงาน ดังนั้นผู้ใช้จึงได้รับส่วนต่อประสานที่เรียบง่ายซึ่งได้รับการปรับให้เหมาะกับงานที่พวกเขากำลังทำงานอยู่ ผู้ใช้ระบุอินพุตบางตัวจากนั้นกดปุ่ม "VERB!" ปุ่ม.

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

บางสิ่งคือ "แอปพลิเคชัน"

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

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

ตอนนี้ลองนึกภาพว่าคุณมีแอปพลิเคชั่นที่สร้างขึ้น; คุณมีปฏิสัมพันธ์กับมันอย่างไรในลักษณะสงบ

  1. ไคลเอ็นต์เริ่มต้นด้วยคำอธิบายไฮเปอร์มีเดียของสถานะปัจจุบัน (เช่น: UI ที่ทำงาน), รวมถึงการควบคุมไฮเปอร์มีเดีย
  2. ลูกค้ายื้อการเป็นตัวแทนของงาน (เช่น: DTO) ไปยังทรัพยากร
  3. ทรัพยากรแยกวิเคราะห์คำขอ HTTP ที่เข้ามาคว้าการแสดงและส่งมอบให้กับแอปพลิเคชัน
  4. แอปพลิเคชั่นทำงาน จากมุมมองของทรัพยากรนี่คือกล่องดำที่มีผลลัพธ์อย่างใดอย่างหนึ่งต่อไปนี้
    • แอปพลิเคชันอัปเดตการรวมทั้งหมด: ทรัพยากรรายงานความสำเร็จไปยังไคลเอนต์นำไปสู่สถานะแอปพลิเคชันใหม่
    • เลเยอร์ต่อต้านการทุจริตปฏิเสธข้อความ: ทรัพยากรรายงานข้อผิดพลาด 4xx ไปยังไคลเอนต์ (อาจเป็นคำขอที่ไม่ดี) ซึ่งอาจส่งผ่านคำอธิบายปัญหาที่พบ
    • แอปพลิเคชันจะอัปเดตการรวมบางส่วน: รายงานทรัพยากรไปยังไคลเอนต์ที่คำสั่งนั้นได้รับการยอมรับและนำลูกค้าไปยังทรัพยากรที่จะให้การแสดงความคืบหน้าของคำสั่ง

ยอมรับเป็น cop-out ตามปกติเมื่อแอปพลิเคชันจะเลื่อนการประมวลผลข้อความจนกว่าจะตอบสนองต่อลูกค้า - โดยทั่วไปใช้เมื่อยอมรับคำสั่งแบบอะซิงโครนัส แต่มันก็ใช้งานได้ดีสำหรับกรณีนี้ซึ่งการดำเนินการที่ควรจะลดความต้องการของอะตอม

ในสำนวนนี้ทรัพยากรแสดงให้เห็นถึงงานของตัวเอง - คุณเริ่มต้นอินสแตนซ์ใหม่ของงานโดยการโพสต์การเป็นตัวแทนที่เหมาะสมไปยังทรัพยากรงานและทรัพยากรที่อินเตอร์เฟซที่มีการประยุกต์ใช้และนำคุณไปสู่

ในเกือบทุกครั้งที่คุณประสานงานหลายคำสั่งคุณต้องการคิดในแง่ของกระบวนการ (กระบวนการทางธุรกิจหรือที่เรียกว่า saga)

มีแนวคิดที่ไม่ตรงกันในแบบจำลองการอ่าน พิจารณาอินเทอร์เฟซตามงานอีกครั้ง หากงานนั้นต้องการแก้ไขการรวมหลายกลุ่มดังนั้น UI สำหรับการเตรียมงานอาจรวมถึงข้อมูลจากการรวมจำนวนมาก หากรูปแบบทรัพยากรของคุณคือ 1: 1 ที่มีการรวมกันนั่นเป็นการยากที่จะจัดการ ให้จัดหาทรัพยากรที่ส่งคืนการแทนข้อมูลจากการรวมหลาย ๆ ครั้งพร้อมกับการควบคุมสื่อหลายมิติที่แมป "งานเริ่มต้น" ที่เกี่ยวข้องกับจุดสิ้นสุดงานตามที่กล่าวไว้ข้างต้น

ดูเพิ่มเติม: REST in Practiceโดย Jim Webber


หากเราออกแบบ API เพื่อโต้ตอบกับโดเมนของเราตามกรณีการใช้งานของเรา .. ทำไมไม่ออกแบบสิ่งต่าง ๆ ในแบบที่ Sagas ไม่ต้องการเลย? บางทีฉันขาดอะไรบางอย่างไป แต่ด้วยการอ่านคำตอบของคุณฉันเชื่อว่า REST นั้นไม่ตรงกับ DDD และควรใช้วิธีการระยะไกล (RPC) ดีกว่า DDD เป็นพฤติกรรมเป็นศูนย์กลางในขณะที่ REST เป็น http-verb centric ทำไมไม่ลบ REST ออกจากรูปภาพและแสดงพฤติกรรม (คำสั่ง) ใน API ท้ายที่สุดพวกเขาอาจถูกออกแบบมาเพื่อตอบสนองสถานการณ์การใช้เคสและโพรบเป็นธุรกรรม ข้อได้เปรียบของ REST คืออะไรถ้าเราเป็นเจ้าของ UI
iberodev
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.