首页 文章

REST API设计 - 通过REST获取具有不同参数但相同url模式的资源

提问于
浏览
51

我有一个与REST网址设计相关的问题 . 我在这里找到了一些相关的帖子:Different RESTful representations of the same resource和这里:RESTful url to GET resource by different fields但是回答并不十分清楚最佳做法是什么以及为什么 . 这是一个例子 .

我有用于表示“用户”资源的REST URL . 我可以使用id或电子邮件地址获取用户,但两者的URL表示形式保持不变 . 通过大量的博客和书籍,我看到人们已经以不同的方式做到了这一点 . 例如

在书中和stackoverflow上的某个地方阅读这个练习(我似乎无法再找到链接)

GET /users/id={id}
GET /users/email={email}

在很多博客上阅读这种做法

GET /users/{id}
GET /users/email/{email}

查询参数通常用于过滤网址所代表的资源的结果,但我也看到了这种做法

GET /users?id={id}
GET /users?email={email}

我的问题是,在所有这些实践中,对于使用api的开发人员来说哪一个最有意义?为什么?我相信在REST网址设计和命名约定方面没有任何规则,但我只是想知道应采取哪条路线来帮助开发人员更好地理解apis .

所有帮助赞赏!

3 回答

  • 65

    根据我的经验, GET /users/{id} GET /users/email/{email} 是最常用的方法 . 如果用户不存在提供的 idemail ,我还希望这些方法返回404 Not Found . 我也不会惊讶地看到 GET /users/id/{id} (虽然在我看来,这是多余的) .

    关于其他方法的评论

    • GET /users/id={id} GET /users/email={email}

    • 我没有看到这个,如果我确实看到了它,那将是非常令人困惑的 . 它's almost like it'试图用路径参数模仿查询参数 .

    • GET /users?id={id} GET /users?email={email}

    • 当你提到使用查询参数进行过滤时,我认为你在头上钉了一针 .

    • idemail (例如 GET /users?id={id}&email={email} )调用此资源是否有意义?如果没有,我不会使用这样的单一资源方法 .

    • 我希望这种方法可以检索具有可选查询参数的用户列表进行过滤,但我不希望 idemail 或任何唯一标识符在参数中 . 例如: GET /users?status=BANNED 可能会返回禁用用户列表 .

    从相关问题中查看此答案 .

  • 2

    从实用的角度来看,你有一组用户:

    /users   # this returns many
    

    每个用户都有一个专用的资源位置:

    /users/{id}    # this returns one
    

    您还可以通过多种方式搜索用户:

    /users?email={email}
    /users?name=*bob*
    

    由于这些都是/ users的查询参数,因此它们都应该返回列表..即使它是1的列表 .

    我写了一篇关于实用的RESTful API设计的博客文章,其中讨论了这一点,其中包括:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

  • 27

    关于用户资源

    在路径 /users 上,您将始终获得返回的集合资源 .

    在路径 /users/[user_id] 上,您将获得表示具有其id [user_id]的用户的单例资源,或者如果没有用户存在所请求的[user_id]则获得404响应(或者如果不允许您访问所请求的用户则禁止(401)资源等) . 每个资源路径只有一个标识符,您可以使用它来查找/标识资源 . 在同一资源路径上不可能对同一资源使用多个标识符 . 如果您在响应中返回了一个资源,那么标识符作为自我HREF包含在响应中以定位/标识资源 .

    您可以使用 GET /查询参数查询路径 /users . 这将返回符合所请求条件的用户的集合 . 返回的集合包含用户资源,所有用户资源都标识自己的HREF .

    关于电子邮件资源

    如果我看一下您对电子邮件的建议,我宁愿考虑以下事项:

    来自用户的电子邮件也是资源 . 所以我认为 /users/[user_id]/emails 会为id为 user_id 的用户返回一组电子邮件地址 . /users/[user_id]/emails/[email_id] 使用user_id和['email_id']返回用户的电子邮件 . 你用作标识符的是你自己,但我会坚持一个整数 . 您可以通过向标识要删除的电子邮件的路径发送 DELETE 请求来删除用户的电子邮件 . 因此,例如 DELETE on /users/[user_id]/emails/[email_id] 将删除具有user_id所拥有的email_id的电子邮件 . 很可能只允许该用户执行此删除操作 . 其他用户将获得401响应 .

    如果用户只能拥有一个电子邮件地址,则可以使用 /users/[user_id]/email 这将返回单个资源 . 用户可以通过 PUT ting更新他的电子邮件地址,或者通过该网址的 POST 更新新的电子邮件地址 . 如果在您的应用程序中您不允许没有电子邮件的用户,如果他向该URL发送了 DELETE 请求,则应回复401 .

相关问题