API web trong giải pháp MVC trong dự án riêng biệt


88

Tôi đang tạo một dự án MVC4 mới và nghiên cứu đã khiến tôi tin rằng việc giao tiếp từ javascript tới phía máy chủ hiện có thể đạt được tốt hơn thông qua khung API web hơn là các hành động của bộ điều khiển. Sự hiểu biết của tôi có đúng về điều này không?

Tôi giả định rằng tôi có thể chia sẻ tất cả các thuộc tính của mình, v.v. giữa các bộ điều khiển API web và MVC, vì vậy, về mặt đối mặt, nó dường như không phải là một thay đổi lớn đối với tôi.

Khi tôi thiết lập các ứng dụng, tôi muốn chia nhỏ các thành phần trong các dự án. Kế hoạch của tôi là có một dự án MVC và một dự án API web. Nhưng tôi đã gặp phải vấn đề. Ví dụ: tôi đã kết thúc với 2 ứng dụng như vậy, thiết lập định tuyến riêng biệt, v.v.

Vì vậy, câu hỏi của tôi là, trong một ứng dụng MVC, khung API web nên nằm trong cùng một dự án hay API web nên được tách thành một dự án riêng và giải quyết các vấn đề?

Câu trả lời:


110

Thật không may, bạn đã sai về điều đó - tôi cho rằng tôi có thể chia sẻ tất cả các thuộc tính của mình, v.v. giữa bộ điều khiển api web và mvc, vì vậy, nhìn chung, nó không có vẻ là một thay đổi lớn đối với tôi.

Nhiều khái niệm được sử dụng bởi Web API và MVC, mặc dù thoạt nhìn tương tự nhau, nhưng thực tế lại không tương thích. Ví dụ: thuộc tính API Web là System.Web.Http.Filters.Filtervà thuộc tính MVC System.Web.Mvc.Filter- và chúng không thể hoán đổi cho nhau.

Điều tương tự cũng áp dụng cho nhiều khái niệm khác - liên kết mô hình (các cơ chế hoàn toàn khác nhau), các tuyến (API Web sử dụng HTTPRoutes không phải Routes, mặc dù cả hai đều hoạt động trên cùng một RouteTable cơ bản), trình giải quyết phụ thuộc (không tương thích) và hơn thế nữa - mặc dù tương tự về bề mặt, rất khác nhau trong thực tế. Hơn nữa, Web API không có khái niệm về khu vực.

Cuối cùng, nếu tất cả những gì bạn đang cố gắng đạt được là có một cách "mới, hợp thời" để phục vụ nội dung JSON - hãy suy nghĩ kỹ trước khi đi theo con đường đó. Tôi chắc chắn sẽ không khuyên bạn nên cấu trúc lại bất kỳ mã hiện có nào trừ khi bạn thực sự muốn nắm bắt HTTP và xây dựng ứng dụng của mình theo cách RESTful.

Tất cả thực sự phụ thuộc vào những gì bạn đang xây dựng. Nếu bạn đang bắt đầu một dự án mới và tất cả những gì bạn cần là cung cấp một số JSON để hỗ trợ ứng dụng web của bạn - miễn là bạn sẵn sàng sống với một số mã có khả năng trùng lặp (như những thứ tôi đã đề cập ở trên), API Web có thể dễ dàng được lưu trữ bên trong cùng một dự án với ASP.NET MVC.

Tôi sẽ chỉ tách Web API thành một dự án riêng nếu bạn định xây dựng một API thích hợp cho dịch vụ trực tuyến của mình - có thể được khách hàng bên ngoài hoặc các thiết bị khác sử dụng - chẳng hạn như cung cấp năng lượng cho các ứng dụng di động của bạn.


2
+1 Câu trả lời xuất sắc. Tôi nghĩ ban đầu cả MVC và WebAPI có thể chia sẻ một số mã, đặc biệt là trong trường hợp bộ lọc, liên kết mô hình, v.v. nhưng chúng hoàn toàn khác nhau.
VJAI 16/10/12

5
Vâng trong trường hợp như vậy, chỉ cần bắt đầu một dự án MVC4 mới trong Visual Studio và khi được nhắc về mẫu dự án (màn hình thứ hai), chỉ cần chọn Web API. Điều đó sẽ cài đặt API Web từ Nuget và trong trường hợp bạn mô tả sẽ hoàn toàn ổn. Những gì bạn nhận được là tệp cấu hình API Web riêng biệt được cắm vào Global.asax. Ngoài ra, bạn có thể muốn tách Bộ điều khiển API thành thư mục riêng biệt (theo mặc định, chúng cùng với bộ điều khiển MVC). Cuối cùng, các tuyến đường mặc định được rõ ràng là cấu hình riêng biệt và không can thiệp với nhau
Filip W

9
Tôi ước gì người dẫn đầu của tôi sẽ đọc bài đăng này trước khi anh ấy thiết kế dự án hiện tại của chúng tôi.
Billdr

2
@FilipW Cảm ơn vì những lời giải thích hay. Tôi cũng có một ứng dụng MVC và sẽ sử dụng WebAPI2 để sử dụng dịch vụ cho các ứng dụng Android. Mặt khác, như David Peden nói bên dưới, bảo mật, bảo trì và triển khai cũng rất quan trọng khi quyết định tạo một dự án riêng biệt mới cho WebAPI. Trong trường hợp đó, hãy ghi nhớ chúng, bạn sẽ đề xuất điều gì? Để tạo một dự án riêng biệt mới cho WebAPI hoặc sử dụng dự án MVC hiện tại? Cảm ơn trước.
Jack

1
Rất tốt "Tôi sẽ chỉ tách Web API thành một dự án riêng nếu bạn định xây dựng một API thích hợp cho dịch vụ trực tuyến của mình - có thể được sử dụng bởi khách hàng bên ngoài hoặc bởi các thiết bị khác nhau - chẳng hạn như cung cấp năng lượng cho các ứng dụng di động của bạn." đánh đinh vào đầu và giúp bạn dễ dàng xác định cách thực hiện.
ozzy432836

27

IMO, bảo mật và triển khai sẽ thúc đẩy quyết định của bạn. Ví dụ: nếu ứng dụng MVC của bạn sử dụng xác thực Biểu mẫu nhưng bạn quan tâm đến việc sử dụng Xác thực cơ bản (với SSL) cho API của mình, các dự án riêng biệt sẽ giúp cuộc sống của bạn dễ dàng hơn. Nếu bạn muốn lưu trữ trang web yout tại www.example.com nhưng lưu trữ API của mình dưới dạng api.example.com (so với www.example.com/api), các dự án riêng biệt sẽ giúp cuộc sống của bạn dễ dàng hơn. Nếu bạn tách các dự án của mình và phân miền phụ cho phù hợp và bạn định sử dụng API của riêng mình từ ứng dụng MVC của mình, bạn sẽ phải tìm cách giải quyết vấn đề Chính sách nguồn gốc tương tự cho các lệnh gọi phía máy khách tới API của bạn. Các giải pháp phổ biến cho việc này là tận dụng jsonp hoặc CORS (tốt nhất là nếu bạn có thể).

Cập nhật (26/3/2013): Sắp có hỗ trợ CORS chính thức: http://aspnetwebstack.codeplex.com/wikipage?title=CORS%20support%20for%20ASP.NET%20Web%20API


Tôi đang cố gắng giải quyết các vấn đề xung quanh quyết định tích hợp API Web với ứng dụng MVC của mình hoặc có nó như một dự án riêng biệt. Tôi đã có thể triển khai thành công ứng dụng Web API HelloWorld cho miền phụ trên máy chủ web của mình. Từ dự án riêng biệt này, tôi có thể sẽ sử dụng Mô hình từ ứng dụng web MVC của mình và mã gọi trong dự án riêng biệt đó. Có vẻ như việc đi theo lộ trình của một dự án riêng có thể dễ dàng hơn, nhưng bạn nghĩ tôi có thể gặp phải những vấn đề gì với cách tiếp cận này?
Ciaran Gallagher

2
Cá nhân tôi sẽ không sử dụng mô hình xem của bạn làm DTO cho API của bạn. Tôi hy vọng rằng quyết định đó sẽ gây ra cho bạn một số đau đớn nghiêm trọng khi các mô hình chế độ xem và chữ ký API của bạn khác nhau. SoC ( en.wikipedia.org/wiki/Seposystem_of_concerns ) rất quan trọng.
David Peden

@DavidPeden Bạn đề xuất tạo một dự án riêng biệt mới cho WebAPI. Có đúng như vậy không? Mặt khác, tôi sẽ tạo một dự án riêng mới cho WebAPI (Tôi hiện có Lớp giao diện người dùng (MVC) và Lớp dữ liệu (Thư viện lớp) trong ứng dụng của mình. Vì vậy, tôi cũng sử dụng DI, nhưng tôi đang phân vân không biết có thể sử dụng không các Thực thể, Kho lưu trữ, Giao diện và Lớp trừu tượng giống nhau trong Lớp dữ liệu cho dự án WebAPI mới được tạo và điều duy nhất tôi phải làm là tạo Bộ điều khiển WebAPI? Hoặc tôi cũng tạo tất cả chúng (Thực thể, Kho lưu trữ, Giao diện và Tóm tắt lớp học) lại cho WebAPI? Có bất kỳ sự trợ giúp nào không?
Jack

1
@ H.Johnson Thật khó để đưa ra lời khuyên chung chung có ý nghĩa nhưng có vẻ như bạn sẽ được lợi từ việc có một lớp dịch vụ ứng dụng đóng gói các thực thể và kho lưu trữ của bạn có thể được tận dụng bởi cả hai giao diện người dùng của bạn (MVC và API).
David Peden

9

Sau một số kinh nghiệm (tạo API cho ứng dụng và cho mvc). Tôi chủ yếu làm cả hai.

Tôi tạo một dự án riêng cho các cuộc gọi api đến từ các máy khách khác hoặc thiết bị khác (ứng dụng Android / IOS). Một trong những lý do là bởi vì xác thực là khác nhau, nó dựa trên mã thông báo (để giữ cho nó không trạng thái). Tôi không muốn kết hợp điều này trong ứng dụng MVC của mình.

Đối với các lệnh gọi javascript / jquery api tới ứng dụng mvc của tôi, tôi muốn giữ mọi thứ đơn giản nên tôi bao gồm một api web bên trong ứng dụng MVC của mình. Tôi không có ý định xác thực dựa trên mã thông báo với các lệnh gọi api javascript của mình, bởi vì nó nằm trong cùng một ứng dụng. Tôi chỉ có thể sử dụng [authorize]thuộc tính trên một điểm cuối API, khi người dùng không đăng nhập, anh ta sẽ không nhận được dữ liệu.

Hơn nữa, khi xử lý giỏ hàng và bạn muốn lưu trữ giỏ hàng của người dùng trong một phiên (khi chưa đăng nhập), bạn cần có điều này trong API của mình cũng như nếu bạn thêm / xóa sản phẩm thông qua mã javascript của mình. Điều này chắc chắn sẽ làm cho API của bạn trở nên trạng thái, nhưng cũng sẽ giảm độ phức tạp trong MVC-API của bạn.


4
Chà @Dimi, đó là một chỉnh sửa vô ích để có được một số phiếu bầu ... Làm thế nào tôi có thể từ chối những điều này?
CularBytes

Làm những gì bạn muốn. Tôi chỉnh sửa không phải bằng phiếu bầu nhưng để có cái nhìn đẹp nhất thì tôi cho là vậy. Tiến lên.
Nhà phát triển

3
@CularBytes Bạn không thể từ chối các chỉnh sửa, nhưng bạn có thể chỉnh sửa lại và khôi phục các thay đổi. Điều này yêu cầu một quy trình đánh giá ngang hàng dưới 2.000 đại diện, nhưng bạn có đủ đại diện để thực hiện ngay lập tức. Tôi đồng ý rằng bản chỉnh sửa không thêm giá trị và đã hoàn trả lại cho bạn.
Dan Bechard


5

Gần đây tôi đã làm gần như tương tự: Tôi bắt đầu với một dự án ứng dụng web MVC 4 mới bằng cách chọn mẫu API Web trong VS2012.

Điều này sẽ tạo một API Web được lưu trữ trong cùng một ứng dụng với MVC.

Tôi muốn chuyển ApiControllers vào một dự án thư viện lớp riêng biệt. Điều này khá dễ dàng nhưng giải pháp có một chút ẩn.

Trong AssemblyInfo.cs của dự án MVC 4, thêm dòng mã tương tự

[assembly: PreApplicationStartMethod(typeof(LibraryRegistrator), "Register")]

Bây giờ bạn cần có lớp LibraryRegistrator (cứ đặt tên là tùy ý)

public class LibraryRegistrator
    {
        public static void Register()
        {
            BuildManager.AddReferencedAssembly(Assembly.LoadFrom(HostingEnvironment.MapPath("~/bin/yourown.dll")));
        }
    }

Trong dự án MVC 4 cũng thêm tham chiếu vào thư viện Api.

Giờ đây, bạn có thể thêm bộ điều khiển Api vào thư viện lớp riêng của mình (yourown.dll).


2

Ngay cả khi dự án của bạn phức tạp đến mức phải đảm bảo hai "mặt trước" thì tôi vẫn chỉ xem xét việc tách webapi thành một dự án riêng biệt như một phương sách cuối cùng. Bạn sẽ phải đau đầu khi triển khai và rất khó để một người mới hiểu cấu trúc của giải pháp của bạn. Chưa kể vấn đề định tuyến.

Tôi muốn giữ không gian tên system.web bị cô lập trong một "lớp trình bày". Mặc dù webapi không được trình bày, nó vẫn là một phần của giao diện ứng dụng của bạn. Miễn là bạn giữ logic trong miền của mình chứ không phải bộ điều khiển, bạn sẽ không gặp quá nhiều vấn đề. Ngoài ra, đừng quên tận dụng các Khu vực.


1
Lý do chính của tôi khi muốn các dự án riêng biệt là API không thực sự là giao diện người dùng. Đó là bậc trung.
Lordcheeto

6
"Sẽ rất khó để một người mới hiểu" không phải là lý do tuyệt vời để chọn một cách tiếp cận này hơn cách khác. Giữ nó đơn giản khi có thể, chắc chắn, nhưng các nhu cầu phức tạp thường đòi hỏi các giải pháp phức tạp. Thay vì viết mã ngu ngốc để phục vụ cho người mới, chúng ta nên đào tạo người mới hiểu và viết mã thông minh.
Dan Bechard

0

Ngoài việc thiết lập DLL riêng cho Web.Api.

Chỉ là một gợi ý:

  1. Tạo dự án
  2. Nugget WebActivatorEx
  3. Tạo aa class Phương thức được gọi khi app_start

    [assembly: WebActivatorEx.PostApplicationStartMethod (typeof (API.AppWebActivator), "Start")]

    [assembly: WebActivatorEx.ApplicationShutdownMethod (typeof (API.AppWebActivator), "Shutdown")]

  4. Đăng ký các tuyến web.api bên trong Phương thức Bắt đầu

    public static void Start () {GlobalConfiguration.Configure (WebApiConfig.Register); }

  5. Tham chiếu Dự án đến Dự án Web. để kích hoạt Phương thức Bắt đầu.

Hi vọng điêu nay co ich.


0

Tôi đã cố gắng chia bộ điều khiển API thành một dự án mới. Tất cả những gì tôi đã làm là tạo một dự án thư viện mới, di chuyển các bộ điều khiển vào bên trong thư mục có tên API. Sau đó, thêm tham chiếu của dự án thư viện vào dự án MVC.

Cấu hình webAPI được để lại trong chính dự án MVC. Nó hoạt động tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.