2015-06-11 100 views
1

我尋找最佳做法的意見和建議與的WebAPI 2工作時:WebAPI如何處理嵌套資源?

可以說我有兩個控制器(用戶和書籍),並願意接受這些路線:

/users/{user_id}/books <= books owned by user_id 

/books <= all books 
/books/{book_id} <= book from id 

具體處理/ users/{user_id}/books的最佳做法是什麼?我正在處理REST API中的很多自定義路由,因此我在方法上使用[RoutePrefix]和[Verb,Route]。

非常感謝!我一直在努力爲常見情況找到更好的解決方案和做法。

回答

1

我喜歡把我所有的返回實體的路由放在同一個控制器上。所以一個BooksController看起來是這樣的:

public sealed class BooksController : ApiController 
{ 
    //Ideally this Repository would be a dependency injected object 
    private readonly IRepository<Book> _repo = new BooksRepo(); 

    [Route("books")] 
    [HttpGet] 
    public IQueryable<Book> GetAll() 
    { 
     return _repo.GetAll(); 
    } 

    [Route("books/{bookId:int}")] 
    [HttpGet] 
    public Book GetById(int bookId) 
    { 
     return _repo.GetById(bookId); 
    } 

    [Route("users/{userId:int}/books")] 
    [HttpGet] 
    public IQueryable<Book> GetBooksByUser(int userId) 
    { 
     return _repo.GetByUser(userId); 
    } 

    [Route("users/{userId:int}/books/{bookId:int}")] 
    [HttpGet] 
    public Book GetUsersBook(int userId, int bookId) 
    { 
     return _repo.GetByUser(userId).FirstOrDefault(book => book.Id == bookId); 
    } 
} 

現在任何返回書籍的路線都應該在這個控制器上。任何返回用戶的路由都將放置在UsersController上。這可以幫助我們保持組織和簡化,因爲路由屬性可以放置在任何控制器上,您可以很容易地在任何控制器上定義任何路由,以便難以追蹤所有可能的路由。

+0

感謝您的回覆,我最終做了這樣的事情! – SlashJ

+0

這是一個很好的答案,但有一個更好的 - > https://stackoverflow.com/questions/9594671/nested-resources-in-asp-net-mvc-4-webapi/16094056#16094056 –

+0

@AndreyMorozov「更好「是基於OP。正如這個問題所述,有許多自定義路由和使用屬性路由。您發佈的答案是使用通用路由,並需要每個映射路由的控制器。 WebApi的偉大之處在於我們擁有的靈活性。更好的是相對的。 – ManOVision