【问题标题】:Codeigniter REST API many to many Relationships?Codeigniter REST API 多对多关系?
【发布时间】:2013-06-05 16:28:28
【问题描述】:

我正在使用 Codeigniter 和 Phil Sturgeon 的 REST API 库开发一个 REST API。

https://github.com/philsturgeon/codeigniter-restserver

我的 REST API 工作正常,但现在我想知道如何为关系建模/REST。例如,我在联系人和收藏夹之间存在多对多关系。

格式(不包括 ?format=json)

GET
/rest_api/contact/{id}
GET
/rest_api/collection/{id}

是否应将关系 (m-m) 视为 REST 资源,例如?

GET (One)
/rest_api/contact_collection/{id}
GET (Collection/All)
/rest_api/contacts_collections/{contact_id}/{collection_id}
PUT (Save)
/rest_api/contact_collection/{contact_id}/{collection_id}
DELETE
/rest_api/contact_collection/{contact_id}/{collection_id}

注意,使用 Phil 的 CodeIngiter REST API,我认为我不能像这样将其拆分:

PUT
/rest_api/contact/{contact_id}/collection/{collection_id}

我也在质疑 ID 应该出现在哪里/如何出现。这两个 ID 应该是请求的 URL 的一部分还是 PUT/POST 数据的一部分?

【问题讨论】:

    标签: php codeigniter rest model


    【解决方案1】:

    我建议将其建模为contactcollections 属性,您可以使用POST ID。即

    GET /collections/{id}
    

     

    GET /contacts/{id}/collections
    

     

    POST /contacts/{id}/collections
    

    或者更好的是,使用 LINKUNLINK (https://datatracker.ietf.org/doc/html/draft-snell-link-method-01) 代替 POST

    LINK /contacts/{id}
    Link: </collections/{id}>;rel="collection"
    

    collection 是 IANA 定义的关系:http://www.iana.org/assignments/link-relations

    【讨论】:

    • Nicholas,您是否建议将 ID 作为 POST 数据的一部分传入(例如 name:'collection_id' 或 'collection_ids'),然后让 contact_model 弄清楚如何处理它们?
    • 是的,我是。 POST 在没有被滥用于其他所有内容时,旨在将新项目“发布”到列表的末尾。 /contacts/{id}/collections 是该列表,如果该资源可以接受 POST 请求,则您不需要任何在 URL 中具有两个 ID 的 PUT 请求。如果集合已经在列表中,您可以假装添加成功,或者如果用户应该知道列表中的内容,则返回 4xx 错误。
    • 我刚刚发现 another SO question 讨论了 REST 中的多对多关系,尽管它没有涵盖您问题的 CodeIgniter 方面。那里的答案比我的更有说服力。基本上,接受的答案说明了我试图传达的内容,尽管最高投票的答案在结构上有所不同并且也有很多优点。
    【解决方案2】:

    尼古拉斯,我赞成你的回答。这是我到目前为止所做的。如果您认为我走在正确的道路上,请告诉我。

    # URI's Explained for base "rest_api" (controller)
    
    # collections resource
    /collections/{id}
    
    # contacts resource
    /contacts/{id}
    
    # collections contacts subresource
    /collections/{collection_id}/contacts/{id}
    Routed to 
    ==> /contacts/id/{id}/collection_id/{collection_id} 
    

    在 Restful 术语中,它有助于不考虑 SQL 和连接,而是更多地考虑集合、子集合和遍历。

    一些例子:

    # getting contact 3 who is in collection 1
    # or simply checking whether contact 3 is in that collection (200 vs. 404)
    GET /collections/1/contacts/3   ==>   /contacts/id/3/collection_id/1
    
    # getting contact 3 who is also in collection 3
    GET /collections/3/contacts/3   ==>   /contacts/id/3/collection_id/3
    
    # adding contact 3 also to collection 2 (RELATIONSHIP)
    PUT /collections/2/contacts/3   ==>   /contacts/id/3/collection_id/2
    
    # getting all collections of contact 3
    GET /contacts/3/collections
    
    # remove contact 3 from collection 1 (RELATIONSHIP)
    DELETE /collections/1/contacts/3
    
    # collection has a new contact, who is not yet added
    POST /contacts
    # from payload you get back the contacts insert id (44), now place contact in collection 1 (RELATIONSHIP)
    PUT /collections/1/contacts/44
    

    如您所见,我不是使用 POST 将联系人放置到集合中,而是使用 PUT,它处理联系人与集合的 n:n 关系。

    使用的 PHP CodeIgniter 路由如下。我真的不确定这是否需要,但允许上面提到漂亮的 URI。

    // Collections
    $route['rest_api/collections/(:num)'] = "rest_api/collections/id/$1";
    
    // Collection Contacts Subresource
    $route['rest_api/collections/(:num)/contacts'] = "rest_api/contacts/collection_id/$1";
    $route['rest_api/collections/(:num)/contacts/(:num)'] = "rest_api/contacts/id/$2/collection_id/$1";
    

    一些 rest_api 控制器方法有点长,但它似乎工作。如果使用,我必须获取 URI 请求参数和查询字符串参数。 Phil 的 CodeIgniter REST API 必须稍微调整一下,以确保在执行 PUT 或 DELETE 请求时获取 URI 参数,因为这些值仅存在于 $this->get() 方法中;奇怪。

    【讨论】:

    • 我对 CodeIgnighter 不熟悉,所以我是从纯理论 REST 的角度来看的。也许我误解了你的模型。要检查联系人是否在集合中,客户端应用程序将 GET /contacts/{id}/collections 并在其中查找指向相关集合的超链接。 (HATEOAS,例如&lt;a href="/collections/4" rel="collection"&gt;foo&lt;/a&gt;,如果表示是 HTML)URL 中的/contacts/{id}/collections 下方将没有任何内容,因此我使用了POST。在选择解决方案之前,请阅读tools.ietf.org/html/draft-snell-link-method-01
    • 此处给出了将现有资源添加到集合的示例:w3-org.9356.n7.nabble.com/Link-and-Unlink-td103940.html#a103942
    【解决方案3】:

    谢谢,

    CodeIgniter-RestServer

    ♦♦♦更改日志

    ♦ 下载 2.5 版:https://github.com/chriskacerguis/codeigniter-restserver/tree/v2.5

    • 如果可能,将使用基节点的单数版本,而不是仅仅查看项目、项目、项目。示例。
    • 重构为使用格式库,该库很快将与 CodeIgniter 合并。
    • 修复了限制错误(限制为 5 将允许 6 个请求)。
    • 添加了无效 API 密钥请求的日志记录。
    • 将序列化更改为序列化。
    • 将所有可见性“私人”更改为“受保护”。
    • 最后带有字符编码的 MIME 现在可以工作了。
    • 修复了 PUT 参数。再次发送一个正文查询字符串就可以了。示例
    • 修复了所有 .foo 扩展名在未提供 get 参数时可以正常工作,并将 .html 移至格式库。
    • 更新了 key.php 示例以使用 config_item('rest_keys_table') 而不是硬编码的 'keys' 表名。
    • 更新了 REST_Controller 以使用 config_item('rest_limits_table') 而不是硬编码的 'limits'。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      相关资源
      最近更新 更多