เราควรเรียก Web API จากแอปพลิเคชัน MVC ในโซลูชันเดียวกันหรือไม่


33

ฉันกำลังทำงานในโครงการใน MVC ที่มีแอปพลิเคชันมือถือสิ่งหนึ่งที่ชัดเจนว่าเราต้องใช้ Web API เพื่อให้สามารถใช้ในแอปพลิเคชันมือถือได้

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

ฉันมีความสับสนเกี่ยวกับโครงสร้างโซลูชันนี้

1) เหตุใดเราจึงควรใช้ Web API และทำการร้องขอ HTTP (ซึ่งใช้เวลานาน) ในการรับหรือวางข้อมูลแทนที่จะเป็นออบเจ็กต์ธุรกิจโดยตรงซึ่งอยู่ในโซลูชันเดียวกัน

2) หลังจากมีข้อโต้แย้งพวกเขาบอกว่าถ้าลูกค้าต้องการโฮสต์ API และเว็บบนคลาวด์เซิร์ฟเวอร์ที่แตกต่างกันและใช้การปรับขนาดเฉพาะบน API หรืออาจต้องการให้มี URL ที่แตกต่างกันสำหรับการเข้าถึง API และเว็บ (ซึ่งเป็นตรรกะ) ดังนั้นในกรณีนั้นเราควรเรียก Web API จากแอปพลิเคชั่น MVC ในโซลูชันเดียวกันหรือไม่

3) ถ้าเรากำลังโฮสต์ API และเว็บในการโฮสต์ที่แตกต่างกันนั่นหมายความว่าเว็บของเราจะใช้ WebClient และมีการโทร HTTP ในแต่ละการนำทาง ถูกต้องหรือไม่

4) ถ้าเราจะทำธุรกิจวัตถุในรูปแบบทั้ง API และเว็บโฮสติ้งบนเซิร์ฟเวอร์ที่แตกต่างกันถ้ามีอะไรเปลี่ยนแปลงใน BL จะต้องอัปเดตบิลด์บนเซิร์ฟเวอร์ทั้งสอง

5) หรือเราควรสร้างเพียงโครงการเดียวสำหรับ API และสามารถเพิ่มมุมมองหรือหน้า html เพื่อพัฒนาเว็บอินเตอร์เฟสดังนั้นด้วยวิธีนี้เราสามารถเรียก API โดยตรงจาก ajax

ตามความรู้ของฉัน # 5 เป็นทางออกที่ดีที่สุดหรือ API สำหรับการเข้าถึงบุคคลที่สามเท่านั้น หากเรามี DB, EF, ชั้นข้อมูลและชั้นธุรกิจในโซลูชันเดียวกันเราไม่ควรใช้ API ในการโทร HTTP และเข้าถึงวัตถุธุรกิจโดยตรง (แก้ไขฉันหากฉันผิด) API เป็นสิ่งจำเป็นสำหรับแอปพลิเคชันมือถือหรือเดสก์ท็อปหรือบุคคลใดก็ตามที่ต้องการเข้าถึงแอปพลิเคชันเพื่อให้เราสามารถมีพื้นที่เก็บข้อมูลและชั้นข้อมูลเดียวกัน

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

ฉันค้นหาทางอินเทอร์เน็ต แต่ไม่ได้รับคำตอบที่น่าเชื่อถือ ฉันพบบล็อกhttp://odetocode.com/blogs/scott/archive/2013/07/01/on-the-coexistence-of-asp-net-mvc-and-webapi.aspxพูดถึงประเด็นเดียวกัน แต่อีกครั้ง ในบล็อกนั้นคำถามของฉันคือทำไมเราต้องพิจารณาสถานการณ์ # 3

อัปเดต: เราสามารถมีโครงการ API และโครงการ MVC ที่แตกต่างกันและเราสามารถเรียก API จากเว็บโดยใช้ jvascript หรือสามารถใช้รูปแบบ MVVM


MVVM หรือ MVC กับรุ่นที่มีวิว?
Andrew Hoffman

เรากำลังใช้ MVC
Ruchir Shah

ตกลงแล้วไม่มีคำตอบที่ถูกต้องจริงๆ มีประโยชน์เพียงโทร API ของคุณเมื่อมันมาถึงการปรับปรุงคุณภาพของพวกเขา (กิน dogfood ของคุณเอง) นอกจากนี้ยังมีประโยชน์ด้านประสิทธิภาพในการโทรแบบ inproc แทนการโทรผ่านบริการ
Andrew Hoffman

Google ต้องผ่านคำถามนี้ซักครั้ง ผลิตภัณฑ์ของพวกเขาเป็นทั้งบริการและเว็บไซต์ ฉันเชื่อว่าพวกเขาตัดสินใจให้เว็บไซต์ใช้บริการของตนเอง
Andrew Hoffman

2
ใช่. programmers.stackexchange.com/questions/148556/…และstackoverflow.com/questions/3590561/…เป็นแหล่งข้อมูลที่ดี บางคนทำบางคนทำไม่ได้ ไม่มีวิธีที่ 'ถูกต้อง' จริง
Andrew Hoffman

คำตอบ:


37

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

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

การโฮสต์ทั้ง API และเว็บไซต์ในโครงการเดียวกัน
ในกรณีนี้คุณอาจมีโซลูชันเดียวที่มีศูนย์ธุรกิจหรือโครงการเลเยอร์มากกว่าและโครงการ MVC / WebAPI แบบไฮบริดเดียว (รวมถึงโครงการอื่น ๆ - ยูทิลิตี้ ฯลฯ )


ทุกอย่างของ Proอยู่ในที่เดียวไม่จำเป็นต้องร้องเท้าในการส่งข้อความที่ซับซ้อน (การโทร HttpClient) คุณสามารถแชร์สถานะเซสชัน (ไคลเอนต์และเซิร์ฟเวอร์ผ่านคุกกี้เซสชัน InProc / OutOfProc ฯลฯ ) การรวมการเชื่อมต่อตรรกะที่ใช้ร่วมกัน ฯลฯ การปรับใช้อาจไม่ง่ายกว่านี้


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

ใช้
ฉันจะใช้โครงสร้างโครงการนี้สำหรับแอปพลิเคชันแบบครั้งเดียวภายในหรือแบบง่าย สร้างระบบที่รวดเร็วสำหรับการติดตามการลงทะเบียนค่ายบาสเกตบอลที่ Y ท้องถิ่น นี่คือสถาปัตยกรรมของคุณ!

WebAPI และเว็บไซต์ในโครงการต่าง ๆ
ฉันมักจะชอบกรณีนี้ .. คุณมีทางออกเดียวกับโครงการ MVC หนึ่งโครงการ (หรือมากกว่า) และหนึ่งโครงการ WebAPI

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

การ
บำรุงรักษาของ Conนั้นค่อนข้างยากขึ้น หลายโครงการหมายความว่าคุณจะต้องมีเจ้าของโครงการ / คุณสมบัติในการติดตามการควบรวมกิจการสัญญา (ส่วนต่อประสาน) การปรับใช้ ฯลฯ การบำรุงรักษารหัสหนี้ทางเทคนิคการติดตามข้อผิดพลาดการจัดการของรัฐ - ทั้งหมดเป็นเรื่องกังวล ตามความต้องการของคุณ แอพพลิเคชั่นประเภทนี้ยังต้องการการวางแผนและการดูแลที่ดีที่สุดเมื่อมันเติบโต

ใช้
สร้างแอปพลิเคชั่นที่สามารถมีผู้ใช้ 100 คนในวันนี้และ 100,000 คนในสัปดาห์หน้า / เดือน? แอปพลิเคชันต้องส่งการแจ้งเตือนจัดการเวิร์กโฟลว์ที่ซับซ้อนและมีหลายอินเทอร์เฟซ (เว็บ + แอพมือถือ + SharePoint) หรือไม่ มีเวลามากมายในมือของคุณและรักที่จะไขปริศนาปริศนากว่า 5,000 ชิ้นในช่วงสุดสัปดาห์? นี่คือสถาปัตยกรรมสำหรับคุณ!

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

  1. ลองใช้เซสชันไร้สัญชาติ ในระบบขนาดเล็กอาจหมายถึงการจัดเก็บคุกกี้ที่เข้ารหัสซึ่งมี ID ภายในของผู้ใช้ปัจจุบันและการหมดเวลาอย่างน้อย ระบบที่ใหญ่กว่าอาจหมายถึงการจัดเก็บคุกกี้ที่เข้ารหัสด้วยรหัสเซสชันแบบง่ายซึ่งอาจถูกดึงมาจากที่เก็บข้อมูล (redis, table storage, DHT , ฯลฯ ) หากคุณสามารถเก็บข้อมูลได้เพียงพอเพื่อที่คุณจะได้ไม่ต้องกดฐานข้อมูลหลัก ในทุกคำขอคุณจะอยู่ในที่ที่ดี - แต่พยายามเก็บคุกกี้ไว้ต่ำกว่า 1k
  2. โปรดทราบว่าอาจมีมากกว่าหนึ่งรุ่น ลองคิดในแง่ของแบบจำลองและการคาดการณ์ (ลิงก์ที่ฉันพบที่นี่คือ .. ไม่ดี .. คิดว่า: รายการสินค้าคงคลังของชายคนหนึ่งเป็นรายการโฆษณาของคำสั่งซื้อของผู้ชายอีกคน - โครงสร้างพื้นฐานพื้นฐานเดียวกัน แต่มีมุมมองที่แตกต่างกัน) บางโครงการมีรูปแบบที่แตกต่างกันสำหรับแต่ละขอบเขต / แนวคิด (เช่นการใช้รูปแบบเฉพาะสำหรับการสื่อสารกับ API ที่เฉพาะเจาะจง
  3. API ของทุกที่! เมื่อใดก็ตามที่วัตถุ / คลาส / โครงสร้างเปิดเผยข้อมูลหรือพฤติกรรมใด ๆ คุณกำลังสร้าง API โปรดทราบว่าหน่วยงานหรือการอ้างอิงอื่น ๆ จะใช้ API นี้อย่างไร ลองคิดว่าคุณจะทดสอบ API นี้อย่างไร พิจารณาสิ่งที่อาจพูดคุยกับ API นี้ (ออบเจ็กต์อื่นผ่านรหัสระบบอื่นผ่านโปรโตคอล) และวิธีการเปิดเผยข้อมูลนั้น (พิมพ์อย่างยิ่ง? JSON? * ไอ * XML?)
  4. สร้างเพื่อสิ่งที่คุณมีไม่ใช่สิ่งที่คุณจินตนาการว่าคุณจะมีสองปีนับจากนี้ คำตอบอื่นอ้างอิงYAGNI - พวกเขาถูกต้องอย่างแน่นอน! การแก้ปัญหาจินตนาการทำให้วันครบกำหนดของคุณเป็นจริง กำหนดเป้าหมายที่มั่นคงสำหรับการทำซ้ำของคุณและตอบสนองพวกเขา ปรับใช้! โครงการในการพัฒนาเป็นโครงการที่มีผู้ใช้เพียงคนเดียว - คุณ!
  5. YMMV (ไมล์สะสมของคุณอาจแตกต่างกัน) มีเพียงหนึ่งสัมบูรณ์ที่นี่: มีปัญหาคุณกำลังสร้างวิธีแก้ปัญหา ทุกอย่างอื่นอยู่ในอากาศอย่างสมบูรณ์ โซลูชันทั้งสองข้างต้นสามารถสร้างความสำเร็จอย่างยิ่งใหญ่และความล้มเหลวในการดูด ทุกอย่างขึ้นอยู่กับคุณเครื่องมือของคุณและวิธีการใช้งาน เหยียบเบา ๆ พัฒนาเพื่อน!

2
คำตอบที่ดี! ฉันหวังว่าฉันจะมอบรางวัลให้คุณสำหรับงานเขียนของคุณ แต่เนื่องจากฉันไม่สามารถคิดอะไรเลยฉันก็แค่ติดตาม Twitter ของคุณ : P
Dan

"พิมพ์อย่างยิ่งหรือไม่ JSON? * ไอ * XML"ฉันจะพลาดอะไร
Alexander Derck

1
@AlexanderDerck ฉันกำลังพูดถึงตัวเลือกการจัดรูปแบบที่แตกต่างกันสามตัว (แม้ว่าจะมีมากกว่านั้น) .. "เรื่องตลก" คือ XML นั้นยากที่จะทำงานด้วยและมักจะสามารถเพิ่มค่าใช้จ่ายที่ดี (serialization / deserialization) นั่นคือไม่ได้บอกว่าบางครั้งไม่มีความจำเป็น (โดยเฉพาะเมื่อทำงานกับกลุ่มภายนอก) ..
บ๊อบบี้ D

6

เข้าถึงวัตถุทางธุรกิจของคุณโดยตรง (ฉันถือว่าคุณหมายถึงในคอนโทรลเลอร์ของคุณ) จะเร็วและง่ายขึ้น

จะเกิดอะไรขึ้นถ้าลูกค้าต้องการโฮสต์ API และเว็บบนคลาวด์เซิร์ฟเวอร์ที่แตกต่างกันและใช้การปรับขนาดเฉพาะบน API หรืออาจต้องการให้มี URL ที่แตกต่างกันสำหรับการเข้าถึง API และเว็บ (ซึ่งค่อนข้างสมเหตุสมผล)

ถ้าอย่างนั้นคุณจะต้องแยกพวกมันออกจากกัน ... แต่นั่นก็ไม่ได้ฟังดูสมเหตุสมผลนักสำหรับฉัน คุณแน่ใจหรือว่าต้องการตอบสนองความต้องการนี้ ฟังดูเหมือน overkill จำ YAGNI - ถ้าคุณไม่ต้องการมันไม่ต้องสร้าง เมื่อคุณต้องการสร้างมัน

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


ฉันเห็นด้วยกับคุณโดยสิ้นเชิงเมื่อสิ้นสุดการปรับขนาดเป็นสิ่งสำคัญและการแยกความกังวลนั้นสำคัญสำหรับฉัน เป็นเรื่องดีเสมอที่จะคิดว่าการสร้างสถาปัตยกรรมระดับ n เป็นการเปลี่ยนแปลงเทคโนโลยีที่สามารถอัพเกรดหรือบำรุงรักษาได้ง่าย ตัวอย่างเช่นการห่อด้วยตัวเทียบท่าเป็นอีกสิ่งที่ควรพิจารณาในอนาคต
Ishwor Khanal

4

ฉันจะบอกว่า; ชอบ MVC ที่เรียก WebAPI ผ่าน HTTPClient มันเป็นเรื่องที่ท่วมท้นไปทั่วตรรกะ "core dll" แต่ข้อได้เปรียบหลักคือระบบโดยรวมของคุณจะมีการเข้าถึงจุดเดียวกับวัตถุโดเมนบน HTTP ... ยังไงก็ตาม Framework ฝั่งไคลเอ็นต์ (AngularJS เป็นต้น) .... ดีกว่าที่จะปฏิบัติต่อ MVC ในฐานะไคลเอนต์อื่น ... และสร้างทีมของคุณให้จัดการ API ที่ดี ...

ให้มันง่าย หวังว่าความช่วยเหลือนี้ ขอบคุณ ..


ไม่แน่ใจว่าทำไมสิ่งนี้ถึงได้ถูกโหวต แต่มันเป็นคำตอบที่ดีที่สุดสำหรับสถาปัตยกรรมที่ดี imo
weagle08

ฉันกำลังไตร่ตรองกับสถานการณ์ของฉันซึ่งฉันคิดว่ามันเป็นความคิดที่ดีที่จะเรียก API จากแอป MVC ของตัวเอง - แต่ฉันคิดว่ามันแตกต่างจากนี้และอาจมีคำถามอื่น ๆ อีกมากมายที่อ้างถึงการโทรนี้จากตรรกะเซิร์ฟเวอร์ ในกรณีของฉันฉันจะเรียกมันจากมุมมองของฉันซึ่งฉันจะให้ Vue สร้าง UIs ที่ซับซ้อนและส่งข้อมูลไปยัง API นั้น จากนั้นฉันก็รู้ว่ามันถูกต้องเพราะในกรณีของฉันมันเรียกจากรายการวิวเซิร์ฟเวอร์และการโทร http ใด ๆ ที่จะต้องทำต่อไปเมื่อพิจารณา UI ชนิดใด ๆ - อาจจะมากกว่านั้นถ้า ASP สร้างมุมมอง แต่ใช้ได้ในสภาพแวดล้อม JS เท่านั้น
Vasily Hall

ดูการเรียก API โดยตรงเป็นความคิดที่ดี .... แต่มุมมอง MVC ถูกสร้างขึ้นจากเซิร์ฟเวอร์ดังนั้นคุณจึงสามารถประมวลผลข้อมูลจากเซิร์ฟเวอร์โดยเฉพาะที่เกี่ยวข้องกับการประมวลผลเซิร์ฟเวอร์) ก่อนที่จะแสดงมุมมองบางส่วน (มุมมอง) ... กรอบ RESS (RESS) : Responsive Web Design + ส่วนประกอบฝั่งเซิร์ฟเวอร์) .... แต่ใช้ PURE Client Frameworks ที่ดีที่สุด (Angular / ReactJS) ถ้าคุณสามารถหลีกเลี่ยง MVC ได้ทั้งหมด ...
Manoj Kumar Bisht
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.