在 RESTful API 中,通常有多個服務服務於不同的目的。雖然為每個獨特的請求創建單獨的服務很誘人,但它可能會導致不必要的重複和臃腫的架構。 ServiceStack 提倡一種不同的方法,鼓勵根據呼叫語義和回應類型對服務進行分組。
服務操作(請求 DTO)應該捕獲服務的獨特操作服務,而它們傳回的 DTO 類型代表實體或資料容器。請求 DTO 應使用動詞(例如「獲取」、「尋找」)來表達其操作,而 DTO 類型應使用名詞(例如「客戶」、「產品」)來表示其實體。
在典型的 GET 要求的情況下,ServiceStack 不需要回應 DTO 中的 ResponseStatus 屬性。相反,如果發生錯誤,將拋出通用 ErrorResponse DTO 並在客戶端上序列化。這消除了在回應中使用顯式 ResponseStatus 屬性的需要。
為了增強可讀性和自我描述,建議在服務合約中使用一致的命名法。為基於唯一識別碼檢索單一結果的服務保留「獲取」動詞。對於傳回多個結果的搜尋服務,請使用「尋找」或「搜尋」前綴。此外,提供清晰且描述性的屬性名稱,以表明其在請求 DTO 中的用途。
根據這些原則,建議使用以下重構的預訂限制服務:
[Route("/bookinglimits/{Id}")] public class GetBookingLimit : IReturn<BookingLimit> { public int Id { get; set; } } public class BookingLimit { public int Id { get; set; } public int ShiftId { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public int Limit { get; set; } } [Route("/bookinglimits/search")] public class FindBookingLimits : IReturn<List<BookingLimit>> { public DateTime BookedAfter { get; set; } }
服務實作可以透過應用[Authenticate]來簡化屬性在服務類別上一次,而不是每個請求DTO。以下程式碼顯示了此實作:
[Authenticate] public class BookingLimitService : AppServiceBase { public BookingLimit Get(GetBookingLimit request) { ... } public List<BookingLimit> Get(FindBookingLimits request) { ... } }
可以使用 ServiceStack 內建的 Fluent 驗證功能來自訂錯誤處理和驗證。您可以使用以下行在AppHost 中註冊驗證器,而不是將驗證器注入到服務中:
container.RegisterValidators(typeof(CreateBookingValidator).Assembly);
對於具有副作用的操作(例如,POST/PUT),您可以定義如下驗證器:
public class CreateBookingValidator : AbstractValidator<CreateBooking> { public CreateBookingValidator() { RuleFor(r => r.StartDate).NotEmpty(); RuleFor(r => r.ShiftId).GreaterThan(0); RuleFor(r => r.Limit).GreaterThan(0); } }
以上是如何在ServiceStack中設計高效且一致的請求DTO?的詳細內容。更多資訊請關注PHP中文網其他相關文章!