動態Web API層

jopen 8年前發布 | 10K 次閱讀 API JavaScript

返回總目錄

本篇目錄

  • 構建動態Web API控制器

    • ForAll 方法
    • 重寫ForAll 方法
    • Http動詞
    • </ul> </li>

    • 動態Javascript代理

      • Ajax參數
      • 單一服務腳本
      • Angular支持
      • Durandal支持
      • </ul> </li>

      • 關于參數綁定

        • FromUri和FromBody特性
        • DTOs vs 原始類型
        • </ul> </li> </ul>

          構建動態Web API控制器

          ABP可以自動地為應用層生成 Web API 層 。比如說我們有一個應用層如下所示:

          public interface ITaskAppService : IApplicationService
          {
              GetTasksOutput GetTasks(GetTasksInput input);
              void UpdateTask(UpdateTaskInput input);
              void CreateTask(CreateTaskInput input);
          }

          我們想把這個服務作為Web API控制器暴露給客戶端。ABP只需要一行配置就可以為該應用服務創建一個Web API控制器:

          DynamicApiControllerBuilder.For<ITaskAppService>("tasksystem/task").Build();

          OK了!在地址為 '/api/services/tasksystem/task' 的地方就創建了一個API控制器,現在客戶端可以使用該應用服務的所有方法。這個配置應該在模塊的Initlize方法中完成。

          我們使用一個API控制器封裝的 ITaskAppService 是一個應用服務。使用API控制器對應用服務進行封裝不是強制的,但是這是傳統推薦的方式。 "tasksystem/task" 一個具有隨機命名空間的API控制器的名字。你應該至少定義一級的命名空間,但是你也可以定義更深層次的命名空間,比如 "myCompany/myApplication/myNamespace1/myNamespace2/myServiceName"'/api/services' 是所有動態生成的Web API控制器的前綴。因此,該API控制器的地址將會是這個樣子的 '/api/services/tasksystem/task' ,而GetTasks方法的地址將會是 '/api/services/tasksystem/task/getTasks' 。因為在javascript中慣例遵循 camelCase 規則,所以方法名都轉成了camelCase格式。

          ForAll 方法

          在應用服務層可能會有很多的應用服務,如果要為這些應用服務都構建API控制器的話,一個一個地構建簡直是費時費力的事情。沒關系,ABP中的DynamicApiControllerBuilder提供了一個為所有應用服務構建Web API控制器的方法,這樣我們只需要調用一次就行了。例如:

          DynamicApiControllerBuilder
              .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
              .Build();

          ForAll方法是接收接口類型的泛型方法。第一個參數是一個程序集,該程序集中含有派生自給定接口的類。最后一個參數是服務前綴的命名空間。比如說我們在給定的程序集中有ITaskAppService和IPersonAppService,對于這個配置的話,服務地址將會是 '/api/services/tasksystem/task' 和 '/api/services/tasksystem/person'。計算服務名稱的方法是:移除Service或者AppService后綴,以及I前綴(對于接口來說)。此外,服務名稱會轉成camel Case(駝峰命名)的格式。如果你不喜歡這種轉換,那么使用'WithServiceName'來決定服務發名稱。此外,還有一個過濾服務的Where方法。除了個別應用服務之外,這個方法在你為其他所有的應用服務構建API控制器時很有用。

          重寫ForAll 方法

          在ForAll方法之后我們可以重寫配置。例如:

          DynamicApiControllerBuilder
              .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
              .Build();
          
          DynamicApiControllerBuilder
              .For<ITaskAppService>("tasksystem/task")
              .ForMethod("CreateTask").DontCreateAction()
              .Build();

          在上面的代碼中,我們為一個程序集中所有的應用服務構建了動態的Web API控制器。然后又為一個應用服務(ITaskAppService)重寫了配置,目的是忽略該應用服務中的CreateTask方法。

          Http動詞

          默認情況下,創建的方法都只能 POST 請求。我們也可以使用不同的方法來改變這種行為。

          WithVerb方法

          我們可以為一個方法使用WithVerb,像下面那樣:

          DynamicApiControllerBuilder
              .For<ITaskAppService>("tasksystem/task")
              .ForMethod("GetTasks").WithVerb(HttpVerb.Get)
              .Build();

          HTTP特性

          我們可以在應用服務的接口的方法上添加HttpGet,HttpPost等特性。

          public interface ITaskAppService : IApplicationService
          {
              [HttpGet]
              GetTasksOutput GetTasks(GetTasksInput input);
          
              [HttpPut]
              void UpdateTask(UpdateTaskInput input);
          
              [HttpPost]
              void CreateTask(CreateTaskInput input);
          }

          使用這些特性之前,應該在項目中添加 Microsoft.AspNet.WebApi.Core Nuget包的引用。

          命名規范

          不用為每個方法都聲明HTTP動詞,你可以使用如下所示的 WithConventionalVerbs 方法:

          DynamicApiControllerBuilder
              .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
              .WithConventionalVerbs()
              .Build();

          在這種情況下,Http動詞會由方法名的前綴決定:

          • Get :方法名以Get開頭。
          • Put :方法名以Put或Update開頭。
          • Delete :方法名以Delete或Remove開頭。
          • Post :方法名以Post或Create開頭。
          • 其他情況,Post是HTTP動詞的默認值

          我們可以通過對特定的方法使用WithVerb方法或者HTTP特性來覆蓋上述慣例。

          動態Javascript代理

          在Javascript中,可以經由Ajax使用動態創建的web api控制器。ABP通過為動態的web api控制器創建動態的Javascript代理簡化了這個。因此,可以在Javascript中像調用一個function一樣來調用一個動態的web api 控制器action:

          abp.services.tasksystem.task.getTasks({
              state: 1
          }).done(function (result) {
              //use result.tasks here...
          });

          Javascript代理是動態創建的。使用之前應該將下面動態的腳本包括在頁面上。

          <script src="/api/AbpServiceProxies/GetAll" type="text/javascript"></script>

          服務方法返回了promise(查看 jQuery.Deferred )。可以在返回的promise后面繼續注冊done,fail,then等回調函數。服務方法內部使用了abp.ajax。如果需要的話,它們會處理錯誤并顯示錯誤信息。

          Ajax參數

          你可以把一個自定義的ajax參數作為第二個參數傳給代理方法。

          abp.services.tasksystem.task.createTask({
              assignedPersonId: 3,
              description: 'a new task description...'
          },{ //override jQuery's ajax parameters
              async: false,
              timeout: 30000
          }).done(function () {
              abp.notify.success('successfully created a task!');
          });

          jQuery.ajax 的所有參數在這里都是有效的。

          單一服務腳本

          '/api/AbpServiceProxies/GetAll'會在一個文件中生成所有的服務代理。使用'/api/AbpServiceProxies/Get?name=serviceName'也可以生成一個單獨的服務代理,只需要在頁面中包括下面的代碼:

          <script src="/api/AbpServiceProxies/Get?name=tasksystem/task" type="text/javascript"></script>

          Angular支持

          ABP可以將動態的API控制器暴露給AngularJs服務。思考下面的例子:

          (function() {
              angular.module('app').controller('TaskListController', [
                  '$scope', 'abp.services.tasksystem.task',
                  function($scope, taskService) {
                      var vm = this;
                      vm.tasks = [];
                      taskService.getTasks({
                          state: 0
                      }).success(function(result) {
                          vm.tasks = result.tasks;
                      });
                  }
              ]);
          })();

          我們可以使用服務的名字(包含命名空間)注射一個服務。然后,可以作為正常的Javascript函數調用它的function。注意,我們注冊到了success句柄上(而不是done),因為它就像在angular的 \(http服務中。ABP使用AngularJs的\) http服務。如果

          你想要傳遞$http配置,可以作為服務方法的最后一個參數傳遞一個配置對象。

          要使用自動生成的服務,應該在頁面中包含需要的腳本:

          <script src="~/Abp/Framework/scripts/libs/angularjs/abp.ng.js"></script>
          <script src="~/api/AbpServiceProxies/GetAll?type=angular"></script>

          Durandal支持

          ABP可以在一個 Durandal 應用的模塊中注入服務代理。看下面的viewmodel:

          define(['service!tasksystem/task'],
              function (taskService) {
                  //taskService can be used here
              });

          ABP配置Durandal(實際上是Require.js)來理解這個'service!'前綴,然后注入合適的javascript服務代理。

          關于參數綁定

          ABP在運行時創建了API控制器。因此,ASP.NET Web API的 模型和參數綁定 可以用于綁定模型和參數。

          FromUri和FromBody特性

          為了在綁定時進行高級控制,可以在服務接口上使用FromUri和FromBody特性。

          DTOs vs原始類型

          我們強烈建議為應用服務和Web API控制器的方法使用DTO作為參數類型,但是你也可以使用原始類型(如string,int,bool或者可空的類型如int?,bool?)作為參數類型。

來自: http://www.cnblogs.com/farb/p/ABPDynamicWebAPI.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!