2013-02-12 55 views
4

我对微软的REST和WebAPI比较陌生。我们正在实施一个集线器REST服务,它将容纳几种类型的对象获取和设置。作为项目的领导者,我负责提出我们正在进行的适当的Uri设计。我想知道在战争中有什么想法更好。是的,我没有使用“标准”一词专门分阶段。.Net WebAPI URI约定用于高级搜索/过滤

这里是我的选择团队和我目前正在娱乐:

Http://servername/API/REST/Ldap/AD/employees?username=jsmith 
Http://servername/API/REST/Ldap/AD/employee/UserName?searchTerm=jsmith (this seems RPC to me) 
Http://servername/API/REST/Ldap/AD/employees/getusername?searchterm?jsmith 

我们还创建SOAP版本,因此URI中的其余部分。

感谢输入

回答

3

要对立的意见,这是我放在一起前一段时间。

https://groups.google.com/d/msg/servicestack/uoMzASmvxho/CtqpZdju7NcJ

public class QueryBase 
{ 
    public string Query { get; set; } 
    public int Limit { get; set; } 
    public int Offset { get; set; } 
} 

[Route("/v1/users")] 
public class User : IReturn<List<User>> 
{ 
    public string Id { get; set; } 
    public string FirstName { get; set; } 
    public string MiddleName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
} 

public class RequestFilterAttribute : Attribute, IHasRequestFilter 
{ 
    #region IHasRequestFilter Members 

    public IHasRequestFilter Copy() 
    { 
     return this; 
    } 

    public int Priority 
    { 
     get { return -100; } 
    } 

public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto) 
{ 
    var query = req.QueryString["q"] ?? req.QueryString["query"]; 
    var limit = req.QueryString["limit"]; 
    var offset = req.QueryString["offset"]; 

    var user = requestDto as QueryBase; 
    if (user == null) { return; } 
    user.Query = query; 
    user.Limit = limit.IsEmpty() ? int.MaxValue : int.Parse(limit); 
    user.Offset = offset.IsEmpty() ? 0 : int.Parse(offset); 
    } 

#endregion 
} 

[Route("/v1/users/search", "GET")] 
[RequestFilter] 
public class SearchUser : QueryBase, IReturn<PagedResult<User>> { } 

public class UsersService : Service 
{ 
    public static List<User> UserRepository = new List<User> 
    { 
     new User{ Id="1", FirstName = "Michael", LastName = "A", Email = "michaelEmail" }, 
     new User{ Id="2", FirstName = "Robert", LastName = "B", Email = "RobertEmail" }, 
     new User{ Id="3", FirstName = "Khris", LastName = "C", Email = "KhrisEmail" }, 
     new User{ Id="4", FirstName = "John", LastName = "D", Email = "JohnEmail" }, 
     new User{ Id="4", FirstName = "Lisa", LastName = "E", Email = "LisaEmail" } 
    }; 

    public PagedResult<User> Get(SearchUser request) 
{ 
    var query = request.Query; 
    var users = request.Query.IsNullOrEmpty() 
        ? UserRepository.ToList() 
        : UserRepository.Where(x => x.FirstName.Contains(query) || x.LastName.Contains(query) || x.Email.Contains(query)).ToList(); 

    var totalItems = users.Count; 
    var totalPages = (int)Math.Ceiling((decimal)totalItems/(decimal)request.Limit); 
    var currentPage = request.Offset; 
    users = users.Skip(request.Offset * request.Limit).Take(request.Limit).ToList(); 
    var itemCount = users.Count; 

    return new PagedResult<User> 
     { 
      TotalItems = totalItems, 
      TotalPages = totalPages, 
      ItemCount = itemCount, 
      Items = users, 
      CurrentPage = currentPage 
     }; 
} 
} 
15

我建议你从布赖恩·马洛伊看看Web API Design。当涉及到搜索和过滤时,他有几个建议。

简化协会 - “?”扫下的复杂

大多数API已经超出了资源的基础水平错综复杂。 复杂性可以包括许多状态,可以更新,更改,查询 以及与资源关联的属性。通过将可选状态 和属性置于HTTP问号后面,开发人员可以使用 来简化基本URL。通过简化资源之间的关联,以及在HTTP问题 标记之下清除参数和其他复杂性,保持您的API直观 。

提示搜索

而一个简单的搜索可以近似为一个足智多谋的API(用于 例如狗/ Q =红色),跨越多个资源的一个更复杂的搜索 要求一个不同的设计。如果你想跨越 资源进行全局搜索,我们建议您按照谷歌模式:

全球搜索

/搜Q =蓬松+皮草

这里,搜索是动词? ; ?q代表查询。

范围内进行搜索

要添加范围搜索,您可以用 搜索范围前面加上。例如,在由资源ID拥有狗搜索5678

/老板/ 5678 /狗?Q =蓬松+皮草

注意,明确的搜索已经从URL下降, 而是依靠参数'q'表示范围查询。

分页和部分响应

支持通过在逗号 分隔的列表添加的可选字段部分反应。

/狗?域=名称,颜色,位置

使用限制偏移,使开发人员可以轻松进行分页 对象。

/狗?极限= 25 &偏移量= 50

+0

@Oppositinal - 非常感谢你,这是伟大的信息。现在我试图解释的另一件事是确认电话。例如,如果我想为开发者提供一个验证票号,我应该在URL中有一个动词,例如http:// serverName/tickets/validate?ticketNumber = 1233或http:// serverName/tickets?validate&ticketNumber = 1233或只是http:// serverName/tickets/1233,他们会得到一个零回?你会怎么做这样的事情? – gcoleman0828 2013-02-13 14:05:44

+0

假设票证号码是票证资源的唯一标识符,那么我的做法是执行GET to/api/v1/tickets/1233并返回404状态(如果具有该编号的票证不存在)。如果您查看我链接的API指南,它建议对于发送本身不是资源的响应的API调用(不调用从数据存储返回的资源),您应该使用非名词动词,例如/ api/v1/validate?ticketId = 1233 – Oppositional 2013-02-13 18:52:21

+0

对于链接文档,为+1 – 2013-10-05 10:26:34