Bạn có nên viết back-end của bạn dưới dạng API không?


322

Tôi đã có một cuộc thảo luận sôi nổi ngày hôm nay về ứng dụng MVC của chúng tôi. Chúng tôi có một trang web được viết bằng MVC ( ASP.NET ) và nó thường theo mô hình làm một cái gì đó trong khung nhìn -> nhấn bộ điều khiển -> bộ điều khiển xây dựng một mô hình (gọi Trình quản lý lấy dữ liệu, xây dựng mô hình trong chính phương thức điều khiển) -> model đi vào xem -> rửa và lặp lại.

Ông nói rằng mã của chúng tôi được ghép quá chặt chẽ. Ví dụ: nếu chúng tôi muốn có một ứng dụng máy tính để bàn, chúng tôi sẽ không thể sử dụng mã hiện có của chúng tôi.

Giải pháp và cách thực hành tốt nhất mà ông nói là xây dựng API, sau đó xây dựng trang web của bạn trên API của bạn và sau đó xây dựng một ứng dụng máy tính để bàn, ứng dụng di động, v.v. rất đơn giản.

Đây dường như là một ý tưởng tồi đối với tôi vì nhiều lý do.

Dù sao, tôi dường như không thể tìm thấy bất cứ điều gì bằng cách googling có thể thảo luận về thực hành này. Có ai có bất kỳ thông tin nào về ưu, nhược điểm, tại sao bạn nên, tại sao bạn không nên đọc thêm?

Một số lý do tôi nghĩ rằng đó là một ý tưởng tồi:

  • Thật quá trừu tượng để chạy phần phụ trợ của bạn khỏi API. Bạn đang cố gắng làm cho nó quá linh hoạt sẽ làm cho nó trở thành một mớ hỗn độn không thể kiểm soát được.

  • Tất cả những thứ được xây dựng trong MVC dường như vô dụng, như vai trò và xác thực. Ví dụ: [Ủy quyền] thuộc tính và bảo mật; bạn sẽ phải tự lăn

  • Tất cả các lệnh gọi API của bạn sẽ yêu cầu thông tin bảo mật được đính kèm và bạn sẽ phải phát triển hệ thống mã thông báo và không có gì.

  • Bạn sẽ phải viết các lệnh gọi API hoàn chỉnh cho mọi chức năng mà chương trình của bạn sẽ thực hiện. Khá nhiều phương pháp bạn muốn thực hiện sẽ cần phải được chạy khỏi API. Nhận / Cập nhật / Xóa cho mỗi người dùng, cộng với một biến thể cho từng thao tác khác, ví dụ: cập nhật tên người dùng, thêm người dùng vào nhóm, v.v. và mỗi người sẽ là một lệnh gọi API riêng biệt.

  • Bạn mất tất cả các loại công cụ như giao diện và các lớp trừu tượng khi nói đến API. Những thứ như WCF hỗ trợ rất nhiều cho các giao diện.

  • Bạn có một phương thức tạo người dùng hoặc thực hiện một số tác vụ. Nếu bạn muốn tạo 50 người dùng, bạn chỉ cần gọi 50 lần. Khi bạn quyết định thực hiện phương pháp này với tư cách là API, máy chủ web cục bộ của bạn có thể đặt tên đường ống kết nối với nó và không có vấn đề gì - máy khách để bàn của bạn cũng có thể gặp phải nó, nhưng đột nhiên việc tạo người dùng hàng loạt của bạn sẽ liên quan đến việc đập API qua Internet 50 lần. tốt Vì vậy, bạn phải tạo một phương thức hàng loạt, nhưng thực sự bạn chỉ đang tạo nó cho các máy khách để bàn. Theo cách này, cuối cùng bạn phải sửa đổi API dựa trên những gì tích hợp với nó và bạn không thể tích hợp trực tiếp với nó, b) làm nhiều việc hơn để tạo ra một chức năng bổ sung.

  • YAGNI . Trừ khi bạn có kế hoạch cụ thể để viết hai ứng dụng hoạt động giống hệt nhau, một ứng dụng web và một ứng dụng Windows chẳng hạn, đó là một lượng lớn công việc phát triển bổ sung.

  • Gỡ lỗi khó hơn nhiều khi bạn không thể bước qua đầu cuối.

  • Rất nhiều hoạt động độc lập sẽ yêu cầu nhiều lần qua lại, ví dụ một số mã có thể có được người dùng hiện tại, kiểm tra người dùng ở vai trò quản trị viên, lấy công ty mà người dùng thuộc về, lấy danh sách các thành viên khác, gửi tất cả Một email. Điều đó sẽ yêu cầu rất nhiều lệnh gọi API hoặc viết phương thức bespoke cho tác vụ cụ thể mà bạn muốn, trong đó lợi ích duy nhất của phương thức bespoke đó là tốc độ nhưng nhược điểm sẽ là không thể thực hiện được.

  • Có lẽ một số lý do nữa là những điều này chỉ ra khỏi đầu của tôi.

Nó chỉ có vẻ như tôi trừ khi bạn thực sự cần hai ứng dụng giống hệt nhau, thì nó thực sự không đáng. Tôi chưa bao giờ thấy một ứng dụng ASP.NET được xây dựng như thế này, bạn phải viết hai ứng dụng riêng biệt (API và mã của bạn) và phiên bản cũng kiểm soát cả hai (nếu trang người dùng của bạn có một trường mới, bạn ' d phải cập nhật đồng thời API và mã tiêu thụ của bạn để đảm bảo không có ảnh hưởng xấu hoặc đặt nhiều công việc bổ sung để giữ cho nó mạnh mẽ).


Chỉnh sửa: Một số phản hồi tuyệt vời, thực sự bắt đầu để có được một ý tưởng tốt về tất cả những gì bây giờ có nghĩa là gì. Vì vậy, để mở rộng câu hỏi của tôi, bạn sẽ cấu trúc một ứng dụng MVC theo cấu trúc API này như thế nào?

Ví dụ: bạn có một trang web hiển thị thông tin về người dùng. Theo MVC, bạn có:

Trang HTML - (CS) hiển thị Trình điều khiển UserViewModel - Gọi GetUser () và tạo một UserViewModel mà nó chuyển đến lớp Trình quản lý xem (loại API của bạn) có phương thức GetUser.

Bộ điều khiển thực hiện GetUser () nhưng bạn cũng muốn có một ứng dụng máy tính để bàn. Điều này có nghĩa là GetUser của bạn cần được hiển thị thông qua một số loại API. Bạn có thể muốn kết nối TCP, WCF hoặc có thể là từ xa. Bạn cũng muốn có một ứng dụng di động sẽ RESTful vì các kết nối liên tục không ổn định.

Vì vậy, sau đó bạn sẽ viết một API cho từng người, một dịch vụ web WCF có phương thức GetUser () và mã chỉ thực hiện return new UserManager().GetUser()? Và một phương pháp api web mvc 4 có làm điều tương tự? Trong khi tiếp tục gọi GetUser trực tiếp trong phương thức bộ điều khiển MVC của bạn?

Hoặc bạn sẽ chọn giải pháp hoạt động cho cả ba (dịch vụ web api REST) ​​và xây dựng mọi thứ trên đó, vì vậy cả ba ứng dụng thực hiện cuộc gọi API (các mvc, cho máy cục bộ).

Và đây có phải chỉ là một kịch bản hoàn hảo về mặt lý thuyết? Tôi có thể thấy các chi phí lớn trong việc phát triển theo cách này, đặc biệt nếu bạn phải phát triển theo cách cho phép bạn thực hiện các thao tác theo cách RESTful. Tôi nghĩ rằng một số điều này đã được đề cập trong các câu trả lời.


Chỉnh sửa 2: Sau khi đọc thêm nội dung, tôi đã đưa ra một nhận xét bên dưới mà tôi nghĩ có thể giải thích nó. Câu hỏi là một chút câu hỏi mẹo tôi nghĩ. Nếu bạn viết back-end của bạn dưới dạng API khiến tôi bối rối khi nghĩ rằng nên có một dịch vụ web duy nhất mà mọi thứ (ứng dụng mvc, ứng dụng máy tính để bàn, ứng dụng di động) gọi để làm công cụ.

Kết luận tôi đã đưa ra là những gì bạn thực sự nên làm là đảm bảo lớp logic kinh doanh của bạn được tách rời chính xác. Nhìn vào mã của tôi, tôi đã làm điều này rồi - bộ điều khiển sẽ gọi trình GetUser()quản lý, sau đó tạo mô hình khung nhìn từ nó để hiển thị với Chế độ xem. Vì vậy, thực sự, lớp logic kinh doanh một API. Nếu bạn muốn gọi nó từ một ứng dụng máy tính để bàn, bạn sẽ cần phải viết một cái gì đó như dịch vụ WCF để tạo điều kiện gọi nó. Thậm chí chỉ cần có một phương thức WCF được gọi GetUser()có chứa mã return MyBusinessLayer.GetUser()là đủ. Vì vậy, API là logic nghiệp vụ và WCF / web api, v.v. chỉ là các tiêu chuẩn của mã để cho phép các ứng dụng bên ngoài gọi nó.

Vì vậy, có một số chi phí, trong đó bạn phải bọc lớp logic nghiệp vụ của mình trong các API khác nhau tùy thuộc vào những gì bạn cần và bạn sẽ phải viết một phương thức API cho mỗi thao tác bạn muốn các ứng dụng khác của mình thực hiện, ngoài ra bạn sẽ cần sắp xếp một cách để xác thực, nhưng đối với hầu hết các phần thì nó đều giống nhau. Dán logic kinh doanh của bạn vào một dự án riêng (thư viện lớp) và có thể bạn sẽ không gặp vấn đề gì!

Hy vọng cách giải thích này là chính xác. Cảm ơn tất cả các cuộc thảo luận / ý kiến ​​nó đã tạo ra.


25
Bạn có thể vui lòng tiết lộ những lý do tại sao bạn nghĩ rằng nó sẽ là một ý tưởng tồi? Ngày nay tôi phải thừa nhận tôi thấy không có lý do gì để KHÔNG làm điều đó. Điều này làm cho, trong số các lợi thế khác, việc chuyển ứng dụng của bạn sang các nền tảng khác dễ dàng hơn nhiều và cho phép linh hoạt tuyệt vời ở mặt trước mà không cần chạm vào mã mặt sau của bạn ...
Laurent S.

12
@SLC: Khi bạn nói API, bạn có nghĩa là API dịch vụ web như giao diện SOAP hoặc REST? Bởi vì bạn nên tạo back-end một API, nhưng bạn không nên biến nó thành một dịch vụ web.
JacquesB

7
@IanNewson "một ứng dụng di động, ví dụ, chúng có xu hướng có ít tính năng hơn." Tôi chưa bao giờ nghe một lý do thuyết phục tại sao các ứng dụng di động phải là công dân hạng hai ... (nhưng mọi người dường như làm theo cách này)
Michael

3
@IanNewson có thể đó chỉ là tôi sau đó ... nhưng tôi luôn thấy mình bị cản trở bởi không thể làm một việc này hay việc khác trên điện thoại đến mức tôi làm rất ít trên di động
Michael

11
Bạn nói YAGNI áp dụng, nhưng kinh nghiệm của tôi là các ứng dụng hoặc được viết lại UI mỗi vài năm hoặc mọi người phàn nàn rằng họ cần một ứng dụng. Chắc chắn sẽ rất tuyệt nếu chúng ta không đánh mất logic kinh doanh của mình bởi vì một công nghệ mặt trước mới đã xuất hiện.
corsiKa

Câu trả lời:


282

Có bạn nên.

Nó không chỉ làm cho mặt sau của bạn có thể sử dụng lại mà còn cho phép bảo mật hơn và thiết kế tốt hơn. Nếu bạn viết phần phụ trợ của mình như một phần của một hệ thống, bạn đang tạo ra một thiết kế nguyên khối không bao giờ dễ dàng mở rộng, thay thế hoặc nâng cao.

Một khu vực nơi này là phổ biến tại thời điểm này là trong Microservices . Trong đó phần phụ trợ được chia thành nhiều dịch vụ nhỏ (hoặc thậm chí lớn) mà mỗi dịch vụ cung cấp một API mà hệ thống máy khách sử dụng. Nếu bạn tưởng tượng sử dụng nhiều nguồn dữ liệu của bên thứ 3 trong ứng dụng của mình, bạn sẽ nhận ra mình có thể đang làm điều này.

Một lợi ích khác là việc xây dựng và bảo trì mỗi dịch vụ có thể được chuyển giao cho một nhóm khác nhau, họ có thể thêm các tính năng cho nó mà không ảnh hưởng đến bất kỳ nhóm sản xuất sản phẩm nào khác. Chỉ khi họ hoàn thành và phát hành dịch vụ của họ, bạn mới bắt đầu thêm các tính năng vào sản phẩm của bạn để tiêu thụ chúng. Điều này có thể làm cho sự phát triển mượt mà hơn nhiều (mặc dù có khả năng chậm hơn về tổng thể, bạn sẽ có xu hướng nhận được chất lượng tốt hơn và dễ hiểu hơn)


Chỉnh sửa: OK tôi thấy vấn đề của bạn. Bạn nghĩ về API như một thư viện từ xa. Không phải vậy. Hãy nghĩ về dịch vụ như là một dịch vụ cung cấp dữ liệu. Bạn gọi dịch vụ để lấy dữ liệu và sau đó thực hiện các thao tác trên dữ liệu đó cục bộ. Để xác định xem người dùng có đăng nhập hay không, bạn sẽ gọi " GetUser" và sau đó xem 'logged on'giá trị. ( YMMV với ví dụ đó, tất nhiên).

Ví dụ của bạn về tạo người dùng hàng loạt chỉ là lý do - không có sự khác biệt nào ở đây, bất cứ điều gì bạn có thể làm trong một hệ thống nguyên khối vẫn có thể được thực hiện trong kiến ​​trúc dịch vụ (ví dụ: bạn sẽ chuyển một mảng người dùng để tạo hàng loạt, hoặc một cái duy nhất để tạo. Bạn vẫn có thể làm chính xác như vậy với các dịch vụ).

MVC đã dựa trên khái niệm về các dịch vụ bị cô lập, chỉ các khung MVC kết hợp chúng thành một dự án duy nhất. Điều đó không có nghĩa là bạn mất bất cứ thứ gì ngoại trừ những người trợ giúp đi kèm mà khung của bạn đang cung cấp cho bạn. Sử dụng một khung khác nhau và bạn sẽ phải sử dụng các trình trợ giúp khác nhau. Hoặc, trong trường hợp này, hãy tự lăn (hoặc thêm chúng trực tiếp bằng thư viện).

Việc gỡ lỗi cũng rất dễ dàng - bạn có thể kiểm tra kỹ lưỡng API một cách tách biệt để bạn không cần gỡ lỗi vào nó (và bạn có thể gỡ lỗi từ đầu đến cuối, Visual Studio có thể đính kèm vào một số quy trình cùng một lúc).

Những thứ như công việc làm thêm thực hiện bảo mật là một điều tốt. Hiện tại, nếu bạn bó tất cả mã vào trang web của mình, nếu tin tặc có quyền truy cập vào nó, họ cũng có quyền truy cập vào mọi thứ, bao gồm DB. Nếu bạn chia nó thành API, hacker có thể làm rất ít với mã của bạn trừ khi họ cũng hack lớp API - điều này sẽ vô cùng khó khăn với họ (có bao giờ tự hỏi làm thế nào kẻ tấn công có được danh sách lớn tất cả người dùng hoặc cc chi tiết của trang web không? họ đã hack hệ điều hành hoặc máy chủ web và nó có kết nối trực tiếp với DB nơi họ có thể chạy " select * from users" một cách dễ dàng).

Tôi sẽ nói rằng tôi đã thấy nhiều trang web (và ứng dụng máy chủ-máy khách) được viết như thế này. Khi tôi làm việc trong ngành dịch vụ tài chính, sẽ không có ai viết một trang web tất cả trong một, vì nó có quá nhiều rủi ro về bảo mật và một phần vì sự phát triển là các GUI đẹp trong xử lý dữ liệu phụ trợ ổn định (tức là di sản) hệ thống. Thật dễ dàng để hiển thị hệ thống DP như một trang web sử dụng kiến ​​trúc kiểu dịch vụ.

Chỉnh sửa lần 2: Một số liên kết về chủ đề (đối với OP):

Lưu ý rằng khi nói về những điều này trong ngữ cảnh của một trang web, máy chủ web nên được coi là lớp trình bày, bởi vì nó là máy khách gọi các tầng khác và cũng vì nó xây dựng các khung nhìn UI được gửi đến trình duyệt để hiển thị. Đây là một chủ đề lớn và có nhiều cách để thiết kế ứng dụng của bạn - tập trung vào dữ liệu hoặc tập trung vào miền (tôi thường coi trung tâm tên miền là 'tinh khiết hơn', nhưng YMMV ), nhưng tất cả đều bắt nguồn từ việc gắn một lớp logic ở giữa khách hàng của bạn và DB của bạn. Nó giống như MVC nếu bạn coi lớp giữa, API, tier tương đương với Model của bạn, chỉ có mô hình không phải là trình bao bọc đơn giản cho DB, nó phong phú hơn và có thể làm được nhiều hơn (ví dụ: tổng hợp dữ liệu từ 2 nguồn dữ liệu, bài đăng -xử lý dữ liệu để phù hợp với API, lưu trữ dữ liệu, v.v.):


2
Đó có phải là một quan điểm của một phi hành gia kiến ​​trúc? Tôi có thể hiểu đoạn 2 và 3 của bạn từ quan điểm dịch vụ, nhưng chúng ta đang nói về GetUser, CreatUser, IsUserLoggedIn và hàng trăm hàm nhỏ trước đây được chuyển đổi thành các lệnh gọi API.
NibblyPig

12
Hãy tưởng tượng bạn đang viết nó như một trang web - tất cả các chức năng nhỏ bé đó không thể tương tác như bạn tưởng tượng, vì vậy bạn sẽ phải lấy dữ liệu và lưu trữ cục bộ trong khi bạn tạo trang của mình (hoặc chuyển chúng dưới dạng dữ liệu cũ có khả năng khách hàng, khi thích hợp với hệ thống). Đối với nhiều điều này, bạn phải thay đổi thiết kế của mình từ "phản ứng theo yêu cầu" sang "dự đoán trước" nhưng hầu hết hệ thống của bạn sẽ thực hiện các cuộc gọi API. Thiết kế API của bạn để ít chi tiết hơn và tập trung vào dữ liệu hơn, vì vậy IsUserLoggedOn không phải là một cuộc gọi API, bạn chỉ cần một "GetUserDetails" sau đó bạn sẽ kiểm tra cục bộ.
gbjbaanb

5
Chúng tôi đã sử dụng phương pháp này tại nơi làm việc cuối cùng của tôi và nó đã làm việc tuyệt vời. Sản phẩm chính của chúng tôi là một ứng dụng web, nhưng chúng tôi có thể tạo một ứng dụng máy tính để bàn và thậm chí các trang tính Excel có thể truy cập cùng các dịch vụ web như ứng dụng web của chúng tôi đã làm cho tất cả dữ liệu của nó và thêm các dịch vụ cho khách hàng của chúng tôi để họ có thể chương trình chống lại họ.
Kik

2
Đây là một lợi ích khác: bạn có thể hiển thị API phụ trợ cho khách hàng trang web của mình. Tại công ty của chúng tôi, chúng tôi đã làm điều này và một số khách hàng của công ty phần mềm lớn (sau khi dùng thử phần phụ trợ trên máy chủ của chúng tôi) đã trả tiền để có phần phụ trợ tự đóng gói như một sản phẩm tự lưu trữ. Tùy thuộc vào sản phẩm, một số khách hàng ít quan tâm đến veneer frontend và quan tâm nhiều hơn đến những gì sản phẩm của bạn thực sự làm - phụ trợ. Đó là một sản phẩm khác để bán.
Reid

2
Điều này cũng làm cho việc sử dụng cùng logic từ dịch vụ web trở nên dễ dàng hơn. Một trong những điều mà các đội của chúng tôi luôn nghĩ rằng chúng tôi sẽ không bao giờ phải làm ... Điều đó cũng giúp việc kiểm tra đơn vị dễ dàng hơn.
ps2goat

87

Bạn không thể tránh việc xây dựng API . Ngay cả khi bạn xây dựng "chỉ là một trang web", nó vẫn sẽ cần lấy dữ liệu từ phần phụ trợ của bạn bằng cách nào đó. Tuy nhiên, bạn quyết định làm điều này, đó là API thực tế của bạn .

Biết được điều này, câu hỏi thực sự không phải là có nên xây dựng API hay không, mà là xây dựng nó như thế nào . Bạn có thể thực hiện nó một cách nhanh chóng như một điều đặc biệt - và thực tế, nhiều trang web được xây dựng chính xác theo cách này - hoặc bạn có thể thiết kế nó một cách cẩn thận để có thể sử dụng trong các bối cảnh khác. Đặt trong bối cảnh này, nó trở nên khá rõ ràng rằng đồng nghiệp của bạn là đúng: bạn nên thực hiện API trước, sau đó xây dựng trang web của bạn trên đầu trang.

Tuy nhiên, điều này mang lại một số mối quan tâm, như bạn chỉ ra. Để giải quyết chúng:

Thật quá trừu tượng để chạy phần phụ trợ của bạn khỏi API. Bạn đang cố gắng làm cho nó quá linh hoạt sẽ làm cho nó trở thành một mớ hỗn độn không thể quản lý được.

Điều đó phụ thuộc vào cách bạn làm điều đó. Như George Pólya đã chỉ ra trong văn bản xuất sắc của mình Cách giải quyết nó , đôi khi "vấn đề chung hơn có thể dễ giải quyết hơn". Điều này được gọi là Nghịch lý của nhà phát minh . Trong trường hợp lập trình, nó thường hoạt động bằng cách tách các mối quan tâm: phần phụ trợ của bạn không còn phải quan tâm đến định dạng của dữ liệu mà nó đưa vào và lấy ra, và do đó mã của nó có thể đơn giản hơn nhiều. Trình phân tích cú pháp và trình kết xuất dữ liệu của bạn không còn phải quan tâm đến những gì xảy ra với dữ liệu họ tạo, do đó, chúng cũng có thể đơn giản hơn. Tất cả đều hoạt động bằng cách chia mã thành nhiều phần dễ quản lý hơn.

Tất cả những thứ được xây dựng trong MVC dường như vô dụng, như vai trò và xác thực. Ví dụ: [Ủy quyền] thuộc tính và bảo mật; bạn sẽ phải tự lăn

Tôi thú nhận rằng tôi cảm thấy vô cùng khó khăn để thông cảm với những người từ chối học các công cụ của họ. Chỉ vì bạn không hiểu việc sử dụng chúng không có nghĩa là chúng vô dụng, và điều đó chắc chắn không có nghĩa là bạn nên tự lăn lộn . Hoàn toàn ngược lại; bạn không nên sử dụng các công cụ của riêng mình cho đến khi bạn hiểu các giải pháp thay thế, để bạn có thể chắc chắn giải quyết các vấn đề tương tự mà chúng làm (ngay cả khi chỉ theo cách riêng của bạn).

Hãy xem xét Linus Torvalds , người nổi tiếng nhất về viết Linux , nhưng cũng viết git : hiện là một trong những hệ thống kiểm soát phiên bản phổ biến nhất trên thế giới. Một trong những yếu tố thúc đẩy trong thiết kế của ông là sự phản đối sâu sắc với Subversion (một VCS cực kỳ phổ biến khác , và được cho là phổ biến nhất tại thời điểm git được viết); anh quyết tâm lấy mọi thứ mà Subversion có thể, và ở bất kỳ mức độ nào có thể, giải quyết những vấn đề đó một cách khác nhau. Để làm điều này, anh ta phải trở thành một chuyên gia về Subversion theo cách riêng của mình , chính xác để anh ta có thể hiểu các vấn đề tương tự và thực hiện một cách tiếp cận khác.

Hoặc, trong quá trình tìm hiểu các công cụ của bạn, bạn có thể thấy mình thấy rằng chúng hữu ích như hiện tại và không cần phải thay thế.

Tất cả các lệnh gọi API của bạn sẽ yêu cầu thông tin bảo mật được đính kèm và bạn sẽ phải phát triển hệ thống mã thông báo và không có gì.

Đúng. Đây là cách nó nên được.

Bạn sẽ phải viết các lệnh gọi API hoàn chỉnh cho mọi chức năng mà chương trình của bạn sẽ thực hiện. Khá nhiều phương pháp bạn muốn thực hiện sẽ cần phải được chạy khỏi API. Nhận / Cập nhật / Xóa cho mỗi người dùng, cộng với một biến thể cho từng thao tác khác, ví dụ: cập nhật tên người dùng, thêm người dùng vào nhóm, v.v. và mỗi người sẽ là một lệnh gọi API riêng biệt.

Không cần thiết. Đây là nơi các kiến ​​trúc như REST phát huy tác dụng. Bạn xác định các tài nguyên mà ứng dụng của bạn làm việc cùng và các hoạt động hợp lý để áp dụng cho các tài nguyên đó và sau đó bạn triển khai các tài nguyên đó mà không phải lo lắng quá nhiều về các tài nguyên khác .

Bạn mất tất cả các loại công cụ như giao diện và các lớp trừu tượng khi nói đến API. Những thứ như WCF hỗ trợ rất nhiều cho các giao diện.

Ngược lại, giao diện trở nên quan trọng hơn nhiều khi bạn đang sử dụng API chứ không phải ít hơn . Chúng đi ra trong các đại diện mà bạn đưa chúng vào. Hầu hết mọi người hiện nay đều chỉ định định dạng dựa trên JSON cho điều này, nhưng bạn có thể sử dụng bất kỳ định dạng nào bạn muốn, miễn là bạn chỉ định rõ. Bạn kết xuất đầu ra của các cuộc gọi của bạn sang định dạng này trên phụ trợ và phân tích nó thành bất cứ điều gì bạn muốn (có thể là cùng loại đối tượng) trên frontend. Chi phí hoạt động rất nhỏ và mức tăng tính linh hoạt là rất lớn.

Bạn có một phương thức tạo người dùng hoặc thực hiện một số tác vụ. Nếu bạn muốn tạo 50 người dùng, bạn chỉ cần gọi 50 lần. Khi bạn quyết định thực hiện phương pháp này với tư cách là API, máy chủ web cục bộ của bạn có thể đặt tên đường ống kết nối với nó và không có vấn đề gì - máy khách để bàn của bạn cũng có thể gặp phải nó, nhưng đột nhiên việc tạo người dùng hàng loạt của bạn sẽ liên quan đến việc đập API qua Internet 50 lần. tốt Vì vậy, bạn phải tạo một phương thức hàng loạt, nhưng thực sự bạn chỉ đang tạo nó cho các máy khách để bàn. Theo cách này, cuối cùng bạn phải sửa đổi API dựa trên những gì tích hợp với nó và bạn không thể tích hợp trực tiếp với nó, b) làm nhiều việc hơn để tạo ra một chức năng bổ sung.

Tạo một phiên bản số lượng lớn của một phương thức hiện có hầu như không phải là thứ mà tôi sẽ gọi là "nhiều công việc hơn". Nếu bạn không lo lắng về những thứ như nguyên tử, phương pháp số lượng lớn có thể kết thúc không nhiều hơn một mặt trận rất mỏng cho bản gốc.

YAGNI . Trừ khi bạn có kế hoạch cụ thể để viết hai ứng dụng hoạt động giống hệt nhau, một ứng dụng web và một ứng dụng Windows chẳng hạn, đó là một lượng lớn công việc phát triển bổ sung.

Không, Yani (Bạn đã cần nó). Tôi đã phác thảo điều đó như trên. Câu hỏi duy nhất là bao nhiêu công việc thiết kế để đưa vào nó.

Gỡ lỗi khó hơn nhiều khi bạn không thể bước qua đầu cuối.

Tại sao bạn không thể bước qua đầu cuối?

Nhưng quan trọng hơn, việc có thể kiểm tra dữ liệu qua lại ở định dạng dễ nhận biết, cắt bỏ tất cả các màn hình hiển thị thực sự có xu hướng làm cho việc gỡ lỗi dễ dàng hơn , không khó hơn.

Rất nhiều hoạt động độc lập sẽ yêu cầu nhiều lần qua lại, ví dụ một số mã có thể có được người dùng hiện tại, kiểm tra người dùng ở vai trò quản trị viên, lấy công ty mà người dùng thuộc về, lấy danh sách các thành viên khác, gửi tất cả Một email. Điều đó sẽ yêu cầu rất nhiều lệnh gọi API hoặc viết phương thức bespoke cho tác vụ cụ thể mà bạn muốn, trong đó lợi ích duy nhất của phương thức bespoke đó là tốc độ nhưng nhược điểm sẽ là không thể thực hiện được.

REST giải quyết điều này bằng cách làm việc trên các đối tượng hoàn chỉnh ( tài nguyên , để sử dụng thuật ngữ của lý thuyết REST), thay vì các thuộc tính riêng lẻ của các đối tượng . Để cập nhật tên người dùng, bạn NHẬN đối tượng người dùng, thay đổi tên và đặt lại người dùng. Bạn có thể thực hiện các thay đổi khác cùng một lúc khi bạn cũng thay đổi tên người dùng. Vấn đề chung hơn trở nên dễ giải quyết hơn, bởi vì bạn có thể loại bỏ tất cả các cuộc gọi riêng lẻ đó để cập nhật các thuộc tính riêng lẻ của một đối tượng: bạn chỉ cần tải nó và lưu nó.

Theo một số cách, điều này không giống với kiến trúc RISC về mặt phần cứng. Một trong những khác biệt chính giữa RISC và CISC (tiền thân của nó) là các kiến ​​trúc CISC có xu hướng bao gồm nhiều hướng dẫn hoạt động trực tiếp trên bộ nhớ, trong khi các kiến ​​trúc RISC có xu hướng hoạt động chủ yếu trong các thanh ghi: trong kiến ​​trúc RISC thuần túy, các hoạt động duy nhất trên bộ nhớ là LOAD (sao chép một cái gì đó từ bộ nhớ vào một thanh ghi) và STORE (lấy một giá trị từ một thanh ghi và đặt nó vào bộ nhớ).

Bạn sẽ nghĩ rằng điều này có nghĩa là thực hiện nhiều chuyến đi hơn từ đăng ký ra bộ nhớ, điều này sẽ làm chậm máy. Nhưng trong thực tế, điều ngược lại thường xảy ra: bộ xử lý (máy khách) thực hiện nhiều công việc hơn giữa các chuyến đi đến bộ nhớ (máy chủ) và đây là nơi tăng tốc xuất phát.

Câu chuyện dài: đồng nghiệp của bạn nói đúng. Đây là con đường để đi. Để đổi lấy một công việc nhỏ, nó sẽ đơn giản hóa đáng kể mã cho Trang web của bạn cho phép tích hợp tốt hơn với các Trang web và ứng dụng khác. Đó là một cái giá phải trả.

Đọc thêm:

  1. Thiết kế API REST - Mô hình hóa tài nguyên

7
Ngay cả những thứ này cũng có các API thực tế . Họ có xu hướng làm cho nhiều nhà phát triển khác trở nên kinh dị, nhưng họ đều là API; chỉ là những người không được thiết kế tốt.
Chiếc thìa ngon nhất

7
Điều đó làm cho một API thực sự kém: nghèo đến mức nhiều người thậm chí không nghĩ đó là API. Nhưng nó vẫn xác định cách mà frontend tương tác với phụ trợ, tuy nhiên cách đó có thể là thô thiển. Nghĩ về điều này như một API giúp thúc đẩy tầm quan trọng của việc làm tốt nó.
Chiếc thìa ngon nhất

1
Tôi nghĩ Linus đã tạo ra git vì cộng đồng Linux đã nổi loạn chống lại việc sử dụng BitCS DVCS thương mại được sử dụng cho kernel.
gbjbaanb

2
Câu đầu tiên của bạn xua tan tất cả sự nhầm lẫn của tôi. Tôi đã liên kết thuật ngữ API với một dịch vụ web và đó là lý do chính khiến tôi rất bối rối.
NibblyPig

4
@IanNewson: có một cách để giao diện với mã, đó là http. Nó có thể có nhiều yêu cầu không liên quan và trả về nhiều dữ liệu không liên quan, nhưng đó là điều khiến nó trở thành một API tệ hại.
jmoreno

63

Tôi biết microservice đang thịnh hành ngay bây giờ, nhưng chúng không phải lúc nào cũng xứng đáng. Vâng, mã ghép lỏng lẻo là mục tiêu. Nhưng nó không nên đến với chi phí của một chu kỳ phát triển đau đớn hơn.

Một nền tảng tốt sẽ là tạo ra một dự án dữ liệu riêng biệt trong giải pháp của bạn. Dự án dữ liệu sẽ là một thư viện lớp .NET. Dự án ASP.NET MVC của bạn sau đó sẽ thêm một tham chiếu vào thư viện dữ liệu và tất cả các mô hình sẽ được lấy từ dự án dữ liệu. Sau đó, khi đến lúc tạo ra một ứng dụng máy tính để bàn hoặc thiết bị di động, bạn có thể tham chiếu cùng một mã. Vì vậy, nó có thể không phải là một API chính thức, nhưng nó sẽ hoạt động như một API. Nếu bạn muốn làm cho nó có thể truy cập dưới dạng API, bạn có thể tạo một dự án web đơn giản hoạt động như một trình bao bọc cho dự án dữ liệu.

Microsoft đã quảng bá khái niệm này, mà họ gọi là Thư viện lớp di động .


13
Tôi đã phải duy trì một dự án trong đó logic được đặt trong lớp UI, gọi các cấu trúc dữ liệu được chia sẻ tương tự. Tôi đã phải sửa một lỗi ba mươi lần vì điều đó ("nếu chúng tôi cần sử dụng lại logic đó, chúng tôi sẽ sao chép và dán! Không cần API"). Đã có một lớp logic (bây giờ có) nó sẽ là đủ với chỉ một sửa chữa.
SJuan76

1
Câu trả lời này, ngoài việc gói thư viện đó vào gói NuGet của riêng nó và lưu trữ nguồn cấp dữ liệu / máy chủ gói NuGet của riêng bạn cũng là một cách hay. Bạn không cần phải lo lắng về các mạng khó khăn và có thể thực hiện tất cả các cuộc gọi cục bộ thành một chuỗi (và do đó nhanh hơn), cộng với việc giới thiệu phiên bản phù hợp với lib lớp của bạn với NuGet giúp các nhóm khác linh hoạt khi họ nâng cấp.
Greg Burghardt

34

Không, bạn không nên . Nếu bạn không có kế hoạch ngay lập tức để tạo các giao diện thay thế (như ứng dụng dành cho thiết bị di động hoặc máy tính để bàn hoặc ứng dụng web riêng biệt) truy cập cùng một phụ trợ, thì bạn không nên giới thiệu một lớp dịch vụ web. YAGNI .

Khớp nối lỏng lẻo luôn được mong muốn (cùng với sự gắn kết cao), nhưng đó là một nguyên tắc thiết kế và không có nghĩa là bạn phải tách các vật thể trên các máy chủ khác nhau! Và API dịch vụ được thiết kế tồi có thể tạo ra sự kết hợp chặt chẽ giữa các ranh giới máy chủ, do đó, việc API không đảm bảo khớp nối lỏng lẻo.

Nếu nhu cầu về API dịch vụ sẽ phát sinh trong tương lai, bạn luôn có thể giới thiệu nó vào thời điểm đó. Miễn là bạn giữ mã của mình được xếp lớp độc đáo (truy cập dữ liệu và logic nghiệp vụ được phân tách rõ ràng logic logic UI), sẽ không khó để giới thiệu muộn hơn so với bây giờ. Và thiết kế kết quả sẽ tốt hơn nhiều khi được thiết kế để đáp ứng yêu cầu thực tế.


Lưu ý Tôi giả sử câu hỏi là bạn có nên tạo API dịch vụ web hay không. Câu hỏi chỉ nói API, nhưng API cũng có thể chỉ có nghĩa là giao diện của thư viện, và dĩ nhiên mỗi lớp sẽ có API theo định nghĩa. Điểm mấu chốt là logic nghiệp vụ và các lớp truy cập dữ liệu của bạn phải được phân tách rõ ràng tạo thành logic UI ở cấp thiết kế, nhưng bạn không nên giới thiệu lớp dịch vụ web nếu bạn không cần nó.


8
Thiết kế xấu bất cứ điều gì không tốt. Xây dựng API không mất nhiều thời gian hơn và có nhiều bằng chứng trong tương lai. Khả năng thích ứng với thay đổi là rất quan trọng hiện nay, tốt hơn là xây dựng một cơ sở vững chắc để đáp ứng mọi nhu cầu mà bạn thậm chí không biết nhưng điều đó có thể đến sớm hơn bạn nghĩ ...
Laurent S.

9
@Bartdude: Giới thiệu sự phức tạp không cần thiết vì mục đích "chứng minh tương lai" cho một tương lai sẽ không đến chỉ là lãng phí tài nguyên.
JacquesB

6
@Bartdude thêm một api chắc chắn là nhiều thời gian hơn. Không biết làm thế nào bạn nghĩ rằng bạn có thể yêu cầu khác.
Ian Newson

13
"Bạn không nên giới thiệu lớp dịch vụ web" API! = dịch vụ web. Nếu bạn có logic kinh doanh của mình đằng sau một API, thì bạn có thể hiển thị API đó dưới dạng dịch vụ web tại một số điểm. Đó không phải là một yêu cầu trước mắt, mặc dù.
Celos

2
@JacquesB: ... vì vậy bạn thực sự không phát triển các tính năng nếu bạn không chắc chắn mình sẽ cần nó. Đó là những gì tôi hiểu từ YAGNI. Tuy nhiên, kiến ​​trúc không phải là một tính năng và các lựa chọn kiến ​​trúc xấu có thể (và rất có thể sẽ) dẫn đến một thất bại thảm hại. Một lần nữa tôi cho rằng cuộc thảo luận này thậm chí có thể xảy ra, đôi khi không phải là vì ngân sách, thời gian tiếp thị, nguồn tài nguyên hoặc lý do thiếu hiểu biết ... Tôi nghĩ rằng chúng ta hoàn toàn có thể đồng ý về điều này, mặc dù Tôi hiểu quan điểm của bạn vì tôi thường có cuộc thảo luận tương tự với chính mình ^ _ ^
Laurent S.

29

Công ty của tôi có một ứng dụng được xây dựng như thế này. Ban đầu, chúng tôi được giao nhiệm vụ xây dựng phần cuối với API cho giao diện người dùng mà nhà phát triển khác đang tạo. Khi nhà phát triển khác không thể phát triển giao diện đó, chúng tôi cũng được ủy quyền xây dựng giao diện người dùng. Trong khi có những lợi ích chắc chắn cho phương pháp này, có một nhược điểm rất lớn: chi phí. Bản dựng ban đầu sẽ đắt hơn đáng kể và bảo trì liên tục sẽ tốn kém hơn, do có nhiều mã hơn để duy trì và có hai hệ thống riêng biệt quá triển khai. Do chi phí thêm, đây luôn luôn là một quyết định kinh doanh, không được đưa ra bởi ý thích bất chợt của các nhà phát triển.

Để đưa ra một con số về nó, tôi ước tính dự án mà tôi đề cập ở trên có chi phí cao hơn 20% do phương pháp này. Bạn không mô tả loại dự án nào bạn đang làm cho loại công ty bạn làm việc, nhưng nếu bạn là người khởi nghiệp xây dựng sản phẩm của họ thì chi phí tăng thêm có thể là sự khác biệt giữa vận chuyển một vài tính năng bổ sung tạo ra sản phẩm của bạn thành công.

Một lý do khác không, ít nhất là không phổ biến, là nếu hoặc khi bạn quyết định tạo giao diện thứ hai đó, hiếm khi có một ánh xạ chức năng một đến một. Nếu bạn tạo một ứng dụng di động chẳng hạn, chúng có xu hướng có ít tính năng hơn. Điều này có nghĩa là một số phương thức API của bạn sẽ không bao giờ được sử dụng lại. Do đó, một thỏa hiệp với đồng nghiệp của bạn có thể là quyết định giữa bạn các cuộc gọi quan trọng / quan trọng nhất và thêm chúng vào API và sử dụng các phương thức truyền thống hơn cho mọi thứ khác.

Một điểm khác cần xem xét là đồng nghiệp của bạn nói rằng bạn sẽ không thể sử dụng lại mã hiện tại của mình, điều này không đúng nếu bạn có sự tách biệt logic kinh doanh. Bạn chỉ cần tạo một trình bao bọc dịch vụ web mỏng xung quanh các API nội bộ của mình, đây không phải là một nhiệm vụ đặc biệt lớn. Sẽ thật ngây thơ khi nghĩ rằng bạn có thể sử dụng lại một lớp dịch vụ web cho một giao diện khác dù sao mà không có thay đổi nào cả.


22

Nó phụ thuộc vào loại ứng dụng và loại thị trường bạn đang ở.

Có sự đánh đổi và lợi ích để đi theo cách này. Nó không phải là một câu trả lời rõ ràng rằng một cách tốt hơn so với cách khác.

Tôi sẽ nói từ kinh nghiệm cá nhân. Tôi là người đã quyết định lấy cơ sở mã mà tôi làm việc theo hướng này vào năm 2007. Cơ sở mã đó hiện đang ở đâu đó theo thứ tự một triệu dòng mã, một nửa trong số đó là mã máy chủ ẩn sau một lượng lớn dịch vụ web API, nửa còn lại là một nhóm khách hàng, máy tính để bàn, web máy tính để bàn, thiết bị di động, tích hợp back-end, v.v ... Quyết định này không phải không có nhược điểm, nhưng với 20/20 tôi có thể nói rằng tôi sẽ làm lại . Hãy để tôi chỉ ra một số sự đánh đổi liên quan.

Những lợi ích

  • Uyển chuyển. Cho dù đó là yêu cầu xây dựng một ứng dụng di động để tăng trải nghiệm máy tính để bàn hay yêu cầu tích hợp với back-end của SAP, tất cả sẽ trở nên dễ dàng hơn khi bạn đã có API để gọi. Khi bạn nhận đủ các yêu cầu này, bạn sẽ phát triển một cách hữu cơ theo API và câu hỏi duy nhất là liệu đó có dịch vụ web tiêu chuẩn trước nó hay không, đó là API nội bộ nơi các dịch vụ web được thiết kế riêng.

  • Khả năng mở rộng (của nhóm). Trong trường hợp của chúng tôi, chúng tôi có nhiều nhóm nhà phát triển khác nhau, tất cả đều xây dựng dựa trên API này. Chúng tôi thậm chí có các nhóm API chuyên dụng, những người nói chuyện với các nhóm khác nhau, tóm tắt các nhu cầu và xây dựng API đa năng từ đó. Đã đến lúc chúng ta thậm chí không nói nữa rằng mọi người đang xây dựng công cụ trên API và không phải ai làm việc đó cho công ty của chúng tôi.

  • Bảo vệ. Việc phân chia rõ ràng giữa các phần không an toàn và an toàn của cơ sở mã của bạn rất hữu ích trong việc giải thích bảo mật. Việc trộn lẫn giao diện người dùng và mã back-end với nhau có xu hướng gây nhầm lẫn các vấn đề.

Đánh đổi

  • Uyển chuyển. Bạn phải thực hiện công việc để "xây dựng" đúng thứ gì đó vào API. Không thể nhanh chóng chạy truy vấn DB từ bên trong mã UI để giải quyết vấn đề cụ thể. Ngoài ra, các API thực sự có thể sử dụng lại phải tính đến rất nhiều trường hợp sử dụng mà giải pháp nhanh thường là giải pháp sai. API trở nên kém linh hoạt hơn để phát triển, đặc biệt là vì đã có quá nhiều mã máy khách (chúng tôi đang chuyển sang API phiên bản vì lý do đó).

  • Tốc độ phát triển ban đầu. Việc phát triển API trước tiên sẽ chậm hơn mà không nghi ngờ gì. Bạn chỉ giành lại được khi bạn có đủ khách hàng được xây dựng trên API. Nhưng sau đó, bạn thấy rằng bạn cần 3 triển khai ứng dụng khách khác nhau trước khi API của bạn phát triển đủ chung chung. Chúng tôi thấy rằng hầu hết các thiết kế API ban đầu của chúng tôi đều sai và phải sửa đổi mạnh mẽ các hướng dẫn của chúng tôi về cách xây dựng các dịch vụ web.

Cá trích đỏ

Bạn đã đề cập đến một loạt các. Họ không thực sự quan trọng trong thực tế.

  • Trừu tượng. API của bạn trở nên đủ trừu tượng để bao gồm tất cả các trường hợp sử dụng mà sản phẩm của bạn cần phục vụ và không nhiều hơn thế. Ngay cả khi không có dịch vụ web, bạn sẽ có API nội bộ thực hiện việc này hoặc có nhiều mã trùng lặp. Tôi thích sự trừu tượng hơn sự trùng lặp.

  • Từ bỏ ngăn xếp MVC phía máy chủ. Ngày nay, hầu hết mọi hệ thống sẽ cần một ứng dụng di động. Sau đó, khi bạn xây dựng các dịch vụ web để phục vụ cho ứng dụng di động đó, bạn sẽ phải tìm ra cách thực hiện xác thực và ủy quyền trong ngữ cảnh API. Nó thực sự ít làm việc hơn khi bạn chỉ có một cách để làm điều đó, cách bạn làm điều đó trong các dịch vụ web của bạn.

  • Hoạt động số lượng lớn. Thường được giải quyết bằng cách tạo API số lượng lớn khởi chạy công việc phụ trợ và trả về id công việc để truy vấn trạng thái. Nó không phải là một thỏa thuận lớn.

  • Gỡ lỗi. Tôi thấy rằng trên toàn bộ nó trở nên dễ dàng hơn để khắc phục sự cố hệ thống. Bạn vẫn có thể đặt điểm dừng trong cả mã mặt trước và mã mặt sau, vì vậy trong thực tế, không khó để vượt qua và bạn có khả năng xây dựng các thử nghiệm api tự động và sử dụng api để giám sát các hệ thống sản xuất.

  • Rất nhiều hoạt động độc lập. Đó là vấn đề về cách bạn thiết kế mọi thứ. Nếu bạn khăng khăng có API CRUD thuần túy, thì có, bạn sẽ gặp phải vấn đề này. Nhưng việc có một số API CQRS để tăng cường thường là một ý tưởng hay và nếu bạn đã chắc chắn rằng bạn có một API nội bộ mà các dịch vụ là một giao diện người dùng, thì bạn có thể dễ dàng sử dụng lại API nội bộ đó để xây dựng các dịch vụ cụ thể đó kịch bản.

Tóm tắt

Trong một hệ thống được sử dụng trong các bối cảnh đủ khác nhau, API sẽ phát triển một cách tự nhiên vì đó là cách dễ nhất để phục vụ cho tất cả các nhu cầu. Nhưng chắc chắn có một trường hợp YAGNI đang diễn ra. Có sự đánh đổi và nó không có ý nghĩa cho đến khi nó có ý nghĩa. Điểm mấu chốt là không giáo điều và giữ một quan điểm cởi mở đối với các cách tiếp cận khác nhau trong kiến ​​trúc để đáp ứng nhu cầu phát triển của sản phẩm.


Thú vị đọc, bạn có thể giải thích những gì bạn đã làm sai khi thiết kế API và những gì bạn đã học?
aaaaaaaaaaaa

3
Ba sai lầm chính là: (1) cung cấp quá nhiều api cho nhu cầu của ui chính, (2) xây dựng trạng thái qua nhiều yêu cầu bằng cách sử dụng phiên (chúng tôi dần trở nên không phiên) và (3) chỉ hỗ trợ việc sử dụng được tạo id id là mã định danh trong đó mã có thể định cấu hình người dùng thường là mã định danh tốt hơn (để tích hợp với các hệ thống bên ngoài, thông thường họ muốn tải mã định danh vào hệ thống của chúng tôi để sử dụng sau này trong api's, thay vì ngược lại). Cả ba cùng với tài liệu yếu và thông báo lỗi không có ích đã khiến api không thể sử dụng mà không có sự trợ giúp.
Joeri Sebrechts

10

Những gì đồng nghiệp của bạn đang mô tả là một kiến ​​trúc hướng dịch vụ. Đây có thể là một cách mã hóa rất lớn, có thể kiểm tra và lành mạnh, nhưng nó thực sự phụ thuộc vào những gì bạn đang làm.

Có một số lợi ích đáng kể đối với SOA, mà tôi sẽ cố gắng liệt kê:

Khả năng mở rộng

Vì mặt sau của bạn được tách rời, mặt trước của bạn chỉ trở thành một loạt các mẫu, thậm chí là các tệp phẳng. Flatfiles rất nhanh và rẻ để phục vụ từ bất kỳ CDN nào. Chúng có thể được thu nhỏ và biên dịch thành HTML tĩnh, sau đó được điền với dữ liệu máy khách.

API của bạn phải duy trì nhất quán, nhưng có thể được hoán đổi cho một công nghệ nhanh hơn mà không phá vỡ ngăn xếp của bạn nếu bạn phát triển vượt trội so với công nghệ hiện có. Bạn có thể làm lại nó trong Go chẳng hạn. Bạn có thể xây dựng lại từng phần và trải tải trên các máy chủ. Miễn là giao diện vẫn giữ nguyên, công nghệ được trừu tượng hóa.

Khả năng kiểm tra

MVC thường khởi động sạch, nhưng trong thực tế, các bộ điều khiển thực tế hiếm khi tập trung vào một tài nguyên. Càng nhiều thứ phương thức điều khiển của bạn làm càng ít kiểm tra chúng trở thành.

Một API vượt qua vấn đề này. Mỗi lệnh gọi API lấy một tài nguyên và phục vụ nó. Sạch sẽ và kiểm tra.

Đảm bảo tách mối quan tâm

Mặt trước và mặt sau của bạn đã ly dị hoàn toàn. Bạn có thể cung cấp mặt trước cho nhà phát triển khác hoặc nhà thiết kế. Đây là MVC được đưa đến một cấp độ khác. Tôi chắc chắn bạn sẽ không muốn từ bỏ MVC. SOA là MVC nhưng hơn thế nữa.

Nhược điểm

Tất nhiên có một số nhược điểm. Một tảng đá thường nhanh hơn để đi với. Nó có thể là những gì bạn đã quen. Nó có thể phù hợp độc đáo hơn vào ngăn xếp của bạn. Công cụ của bạn có thể được tối ưu hóa để tạo nguyên khối.

Theo tôi, không có lý do nào đặc biệt tốt và bạn có thể cân nhắc việc trang bị lại nếu chúng áp dụng cho bạn.


Đây là câu trả lời rõ ràng nhất cho đến nay.
Tony

7

Có rất nhiều câu trả lời hay ở đây vì vậy tôi sẽ chỉ thêm kinh nghiệm thực hiện của mình.

Đây là cách tôi làm mọi thứ:

  • Tạo Lớp truy cập cơ sở dữ liệu xử lý tất cả / chỉ tương tác DB (thường là SQL thủ công được sử dụng cho tốc độ và kiểm soát, không có ORM) . Chèn, cập nhật, xóa, chọn ...
  • Tạo một interface( virtual class) hiển thị / thực thi các hàm API tôi cần. Khi được triển khai, họ sẽ sử dụng các hàm DBAL chuyên dụng cao để đạt được kết quả. Nó cũng giúp tôi thực thi API ở cấp trình biên dịch để tôi đảm bảo việc triển khai Server + API có tất cả các chức năng được tích hợp.
  • Tạo một lớp thứ hai thực hiện giao diện (đây là API thực tế) và thực thi các hạn chế bảo mật. Bạn cũng tương tác với các API bên ngoài tại đây.
  • Trang web sẽ sử dụng trực tiếp Lớp thứ hai (để thực hiện) mà không cần sử dụng API có thể truy cập từ xa (như SOAP, JSON) .
  • Một máy chủ độc lập được xây dựng để thực hiện giao diện và hiển thị Lớp thứ hai dưới dạng API có thể truy cập từ xa thực tế cho các máy khách / máy tính để bàn bên ngoài (truy cập không phải trang web) . Tất cả những gì nó làm là giải mã các yêu cầu và mã hóa các phản hồi và quản lý / ngắt kết nối máy khách. Nó cũng hỗ trợ các khả năng đẩy lùi để thông báo hàng loạt cho khách hàng về các sự kiện được tạo bởi các đồng nghiệp được kết nối khác (chức năng mà một trang web thường không yêu cầu) .

Vì vậy, về mặt kỹ thuật, API là Lớp thứ hai. Bạn sử dụng nó trực tiếp với trang web và hiển thị nó cho các máy khách từ xa thông qua một máy chủ. Mã được sử dụng lại và không có đoạn mã nào có thể sử dụng lại được. (sống và chết theo quy tắc này và mọi thứ đều tuyệt vời) Giúp duy trì, kiểm tra ... mọi thứ.

Bạn không bao giờ kết nối trang web với máy chủ API trên máy tính để bàn / thiết bị di động (trừ khi trang web của bạn là AJAX và chạy trên JSON) . Nhưng nếu trang web hiển thị nội dung động trong đánh dấu, thông qua API trung gian sẽ bắn hiệu suất của bạn. Trang web cần phải nhanh chóng! Truy cập máy khách từ xa có thể chậm hơn một chút.

PS : Vâng, bảo trì phức tạp hơn một chút vì nhiều bánh xe hoạt động cùng nhau nhưng về lâu dài sẽ dễ dàng hơn. Vì vậy, nếu dự án của bạn có nghĩa là tồn tại trong một thời gian và hơi phức tạp, hãy luôn có API. Nó cũng dễ dàng hơn nhiều để tự kiểm tra từng lớp.


Nghe có vẻ khá hay và có nhiều ý nghĩa, đặc biệt là đặt giao diện trên các hàm loại API của bạn. Tôi sẽ thử thiết lập này vào lần tới khi tôi tạo một dự án!
NibblyPig

6

Điểm gây tranh cãi không phải là nếu bạn nên sử dụng API, mà thực sự là "API". Cách thay thế duy nhất để sử dụng API được thiết kế là sử dụng API là một mớ hỗn độn mã ngẫu nhiên. Bạn viết rằng API làm cho mọi thứ "quá linh hoạt", điều này sẽ khiến mọi thứ không thể quản lý được. Điều này chỉ ra sự hiểu lầm đầy đủ và kỹ lưỡng về API là gì. Nếu sự hiểu lầm đó không được chia sẻ giữa bạn và đồng nghiệp, thì bạn đã lãng phí rất nhiều thời gian bằng cách tranh cãi về những điều hoàn toàn khác nhau.

Bằng cách không sử dụng API được xác định rõ, bạn có thể làm bất cứ điều gì bạn muốn. Theo định nghĩa đây là tùy chọn linh hoạt nhất. Ngoài ra, theo định nghĩa "làm bất cứ điều gì bạn muốn" vẫn là một API. Công việc duy nhất của API là loại bỏ tính linh hoạt. Bằng cách loại bỏ tính linh hoạt, một API tốt sẽ khuyến khích người dùng thực hiện những điều tương tự theo những cách tương tự.

Tất nhiên, một API xấu có thể cung cấp quá nhiều hoặc quá ít tính linh hoạt hoặc thậm chí cả hai cùng một lúc. Một API được thiết kế thực sự kém có thể giết chết một dự án thậm chí còn nhanh hơn cả phương pháp "mọi thứ diễn ra". Tuy nhiên, cách tốt nhất chỉ đơn giản là có các lập trình viên có năng lực, những người phát triển và phát triển API cùng với ứng dụng của bạn.

Thí dụ

• Rất nhiều hoạt động độc lập sẽ yêu cầu nhiều lần qua lại, ví dụ một số mã có thể có được người dùng hiện tại, kiểm tra người dùng ở vai trò quản trị viên, lấy công ty mà người dùng thuộc về, lấy danh sách các thành viên khác, gửi cho họ tất cả một email. Điều đó sẽ yêu cầu rất nhiều lệnh gọi API hoặc viết phương thức bespoke cho tác vụ cụ thể mà bạn muốn, trong đó lợi ích duy nhất của phương thức bespoke đó là tốc độ nhưng nhược điểm sẽ là không thể thực hiện được.

Số lượng lệnh gọi API này sẽ yêu cầu trên một API kha khá có thể là 1. Có, nó không linh hoạt, nhưng tại sao bạn lại muốn nó linh hoạt?


4

Ông nói rằng mã của chúng tôi được ghép quá chặt chẽ. Ví dụ: nếu chúng tôi muốn có một ứng dụng máy tính để bàn, chúng tôi sẽ không thể sử dụng mã hiện có của chúng tôi.

Vâng, phải không? Nếu không, thì đó là một tuyên bố không liên quan.

Tôi muốn nói, nếu bạn định xây dựng một ứng dụng mới vào năm 2015, thì hãy nghiêm túc xem xét một cái gì đó với giao diện người dùng có API và không phải các trang HTML do máy chủ tạo. Có chi phí rõ ràng nhưng cũng có lợi ích rõ ràng.

Nhưng nếu bạn có một trang web hiện tại không có kế hoạch cụ thể để có một vài giao diện khác nhau (theo như tôi có thể nói), thì những bình luận của anh ta chỉ là không liên quan.


4

Phiên bản ngắn: Bộ điều khiển của bạn có hiệu quả API bất kể là gì; Mặc dù ASP.NET có thể che khuất điều đó.

Phiên bản dài hơn:

Hãy suy nghĩ về một ứng dụng web MVC cơ bản cung cấp thông tin về bia và tùy ý bán cho bạn một cái. Các tuyến đường trông như thế nào?

/sign_in
/sign_out
/beer
/beer/{beer_name}
/order
/order/{order_number}

Trong một ứng dụng web thông thường, có thể có một vài tuyến phụ trợ như:

/beer/new
/beer/{beer_name}/edit
/beer/{beer_name}/delete
/order/new
/order/{order_number}/edit
/order/{order_number}/delete

Trong API Web không bắt buộc, vì chúng được suy ra từ phương thức HTTP.

Với sự đối xứng ở trên, tôi nghĩ rằng điều này tạo ra một trường hợp khá hấp dẫn rằng API và Trình điều khiển của bạn rất gần đến mức chúng cũng có thể giống nhau.

Sau khi thực hiện một số hoạt động đào, tôi đã xác định rằng đây có thể là trạng thái của mọi thứ cho bạn tùy thuộc vào phiên bản ASP.NET bạn đang sử dụng. MVC 5 cũ hơn và trước đó thiếu các quy ước và giao diện để thống nhất rõ ràng hai triển khai. Trong các phiên bản cũ, Ứng dụng web trả về sẽ hiển thị Chế độ xem trong khi API cung cấp cho HTTPResponse. Tuy nhiên, trong cả hai trường hợp, họ đang tạo ra cùng một phản hồi chính xác về mặt ngữ nghĩa.

Nếu bạn đang sử dụng MVC 6, bạn sẽ có cả hai trong một lớp trình điều khiển hợp nhất có thể thông minh về những gì nó trả về. Tôi chưa tìm thấy bất kỳ mã ví dụ ASP tốt nào cho mô hình này, nhưng tôi đã tìm thấy một số mã Rails có cùng mẫu. Hãy xem xét bộ điều khiển này để "thích" từ dự án Diaspora . Mỗi phương thức của bộ điều khiển có các tuyến được xác định bởi một "quy ước tài nguyên" ở đây tương đương với LCRUD trong API.

Tuy nhiên, nếu bạn đọc các triển khai, mỗi ứng dụng có thể phản hồi HTML, Mobile HTML hoặc JSON. Điều này, kết hợp với một quy ước để tìm các khung nhìn, hoàn toàn thống nhất Ứng dụng web và API Web. Bạn cũng sẽ lưu ý rằng không phải tất cả các phương thức đều thực sự cung cấp từng phản hồi (điều này hợp lý, vì UI có thể yêu cầu các phương thức mà API sẽ không và ngược lại).

Đây là một sự không phù hợp trở kháng bởi vì loại ASP.NET đã phát hiện ra tất cả những điều này muộn trong khi Rails đã nắm lấy sự đối xứng trong một thời gian và làm cho nó rất rõ ràng.

Đầu cơ:

Đồng nghiệp của bạn có thể cả đúng và sai, tùy thuộc vào phiên bản ASP bạn đang sử dụng. Trong phiên bản MVC cũ, sự khác biệt giữa API và Ứng dụng có thể đã biến nó thành "cách thực hành tốt nhất" để xây dựng API trước vì mô hình của ASP.NET không thực sự cho phép tái sử dụng mã tốt ở đó.

Với mã mới hơn, việc sử dụng mã hợp nhất sẽ hợp lý hơn vì việc sử dụng lại mã dễ dàng hơn với lớp cơ sở của bộ điều khiển hợp nhất.

Tuy nhiên, trong cả hai trường hợp, Bộ điều khiển thực sự là API.


Câu hỏi này đã được trả lời cho đến chết, nhưng tôi không nghĩ các câu trả lời khác khá rõ ràng. "Bạn không thể tránh việc xây dựng API." câu trả lời là khá nhiều tại chỗ, và câu trả lời được chấp nhận nhảy xung quanh cùng một vấn đề; nhưng cả hai đều không giải quyết vấn đề cụ thể theo cách mà tôi cảm thấy đã lái xe về nhà.
Jayson

Nhiều câu trả lời hơn, họ giúp nhận được sự đánh giá đúng đắn về những gì người khác cảm nhận về điều này.
NibblyPig

2

Khi tôi bắt đầu sự nghiệp của mình vào năm 2006, loại kiến ​​trúc này là tất cả những cơn thịnh nộ trong thế giới .NET. Tôi đã làm việc trên 3 dự án riêng biệt được hình thành vào giữa những năm 2000 với một dịch vụ web giữa lớp logic kinh doanh và giao diện web. Tất nhiên ngày nay các dịch vụ web là SOAP nhưng nó vẫn là kiến ​​trúc tương tự. Những lợi ích được cho là khả năng chuyển đổi trước hoặc phụ trợ và thậm chí phát triển chương trình máy tính để bàn. Cuối cùng YAGNI đã chứng minh là đúng. Tôi chưa bao giờ thấy bất kỳ điều này xảy ra. Tất cả thời gian này tôi chỉ thấy chi phí chia tách dự án theo cách này. Tôi thậm chí đã kết thúc việc tách dịch vụ web ra khỏi một trong các dự án (mất nửa năm để loại bỏ nó từng bước trong khi làm những việc khác) và cả nhóm đều vui mừng. Tôi chưa bao giờ thử cách tiếp cận đó và tôi sẽ không trừ khi đưa ra một lý do rất cụ thể. 5 năm kinh nghiệm dùng thử kiến ​​trúc này đã dạy tôi rằng tôi sẽ không cần nó và không có chuyên gia nào nói với tôi điều ngược lại sẽ thuyết phục tôi. Chỉ một dự án mà tôi cần nó có thể làm điều đó.

Bây giờ được nói tôi cố gắng hết sức để phát triển một lớp giữa logic nghiệp vụ và bộ điều khiển / người thuyết trình. Ví dụ: tôi có một lớp dịch vụ, tôi không bao giờ phơi bày các vấn đề, sử dụng giao diện cho tất cả các dịch vụ của mình và đưa chúng vào bộ điều khiển với IoC. Nếu tôi cần một dịch vụ web trong kiến ​​trúc của mình, tôi sẽ có thể giới thiệu nó với chi phí hợp lý. Tôi chỉ không muốn trả chi phí này trước.

Ngoài ra tôi khá thích ý tưởng về microservice nhưng sự hiểu biết của tôi là microservice có nghĩa là các mô-đun dọc thay vì các lớp ngang. Ví dụ: nếu bạn đang xây dựng facebook, tính năng trò chuyện sẽ là một dịch vụ riêng được triển khai riêng trên các máy chủ của riêng họ, v.v ... Đây là loại dịch vụ độc lập mà tôi khuyến khích.


2

Bên thứ ba sẽ sử dụng nó? Vâng, bạn nên .

Bạn có kế hoạch sử dụng lại nó trong một tương lai không xa? Vâng, bạn nên.
Bạn sẽ là bên thứ ba của bạn , có API tài liệu - hoặc tài liệu - hoặc API của bên thứ ba có thể sử dụng được sẽ cung cấp cho bạn khả năng sử dụng lại và mô đun hóa vững chắc.

Bạn đang vội? Không, bạn không nên.
Tái cấu trúc sau đó dễ dàng và nhanh hơn hầu hết các phương pháp và giáo viên dự đoán và nói. Điều quan trọng hơn là có một cái gì đó hoạt động (ngay cả với một thiết kế bên trong tồi, vì nó có thể và sẽ được tái cấu trúc) hơn là không có gì cả. (nhưng với một thiết kế nội bộ đáng kinh ngạc , wohoo)

Mặt trước có thể không bao giờ nhìn thấy ánh sáng trong ngày vì lý do? Vâng, bạn nên .
Tôi đã thêm lý do này bởi vì, tốt, điều này đã xảy ra với tôi rất nhiều.
Và ít nhất tôi còn lại với các thành phần của mình để tái sử dụng và phân phối lại, v.v.


1

Có câu trả lời tốt ở đây. Tôi đăng bài này như một câu trả lời một phần; nó có lẽ sẽ tốt hơn như là một bình luận Tuy nhiên, việc dán cùng một bình luận trên nhiều bài viết là không tốt.

Người ta không thể yêu cầu YAGNI là một lý do cho việc không tạo API.

API là một điểm cuối thử nghiệm tự nhiên và hợp lý. Do đó, ngay từ ngày 0, có hai ứng dụng sử dụng API: UI và bộ thử nghiệm. Một cái có nghĩa là cho con người, cái kia có nghĩa là cho máy móc. Họ nhất thiết phải khác nhau. Kiểm tra hành vi front-end là một nhiệm vụ khác nhiều so với kiểm tra hành vi back-end. Do đó, các kỹ thuật, và có lẽ các công cụ, là hoàn toàn khác nhau. API cho phép công cụ tốt nhất được sử dụng cho công việc. Hơn nữa, với sự phân tách được API cung cấp, người kiểm tra giao diện người dùng không phải kiểm tra chức năng phụ trợ.

API cũng giúp giữ cho các lập trình viên phía trước thoát khỏi mối quan tâm của các lập trình viên phía sau và ngược lại. Đây là những kỹ năng rất khác nhau tại công ty chúng tôi; API cho phép chúng tôi tập trung vào nơi chúng tôi mạnh nhấ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.