composite key resource REST service

前端 未结 2 1413
[愿得一人]
[愿得一人] 2021-02-05 04:28

I\'ve come across a problem at work where I can\'t find information on the usual standard or practice for performing CRUD operations in a RESTful web service against a resource

相关标签:
2条回答
  • 2021-02-05 04:56

    I suggest:

    • POST /api/PartsProductsAssoc: Create link between part and product. Include part and product ids in POST data.
    • GET, PUT, DELETE /api/PartsProductsAssoc/<assoc_id>: read/update/delete link with <assoc_id> (not part or product id, yes, this means creating a new column in your PartsProductsAssoc table).
    • GET /api/PartsProductsAssoc/Parts/<part_id>/Products: get list of products associated with the given part.
    • GET /api/PartsProductsAssoc/Products/<product_id>/Parts: get list of parts associated with the given product.

    Reasons to take this approach:

    • Single, fully-qualified URI for each link.
    • Modifying a link modifies a single REST resource.

    For more info, see https://www.youtube.com/watch?v=hdSrT4yjS1g at 56:30.

    0 讨论(0)
  • I too like the aesthetics of /api/Products/1/Parts/2. You could also have multiple routes go to the same action, so you could double up and also offer /api/Parts/2/Products/1 as an alternate URL for the same resource.

    As for POST, you already know the composite key. So why not eliminate the need for POST and just use PUT for both creation and updates? POST to a collection resource URL is great if your system generates the primary key, but in cases where you have a composite of already known primary keys, why do you need POST?

    That said, I also like the idea of having a separate ProductPartAssocController to contain the actions for these URL's. You would have to do a custom route mapping, but if you're using something like AttributeRouting.NET that is very easy to do.

    For example we do this for managing users in roles:

    PUT, GET, DELETE /api/users/1/roles/2
    PUT, GET, DELETE /api/roles/2/users/1
    

    6 URL's, but only 3 actions, all in the GrantsController (we call the gerund between users and roles a "Grant"). Class ends up looking something like this, using AttributeRouting.NET:

    [RoutePrefix("api")]
    [Authorize(Roles = RoleName.RoleGrantors)]
    public class GrantsController : ApiController
    {
        [PUT("users/{userId}/roles/{roleId}", ActionPrecedence = 1)]
        [PUT("roles/{roleId}/users/{userId}", ActionPrecedence = 2)]
        public HttpResponseMessage PutInRole(int userId, int roleId)
        {
            ...
        }
    
        [DELETE("users/{userId}/roles/{roleId}", ActionPrecedence = 1)]
        [DELETE("roles/{roleId}/users/{userId}", ActionPrecedence = 2)]
        public HttpResponseMessage DeleteFromRole(int userId, int roleId)
        {
            ...
        }
    
        ...etc
    }
    

    This seems a fairly intuitive approach to me. Keeping the actions in a separate controller also makes for leaner controllers.

    0 讨论(0)
提交回复
热议问题