Skip to main content
Background Image

Add and Remove Custom Methods - Summary

·374 words·2 mins

Motivation
#

  • Many-to-many relationships are common and sometimes complex.
  • The association-resource pattern is flexible but can be heavyweight.
  • This chapter explores a simpler alternative: hide the association resource and manage relationships via custom add / remove methods, accepting specific limitations.

Overview
#

  • Replace an explicit association resource with custom methods that create/delete associations and expose only the existence of the relationship.
  • Consumers call concise methods (or HTTP endpoints) to add or remove associations; internal representation is hidden.
  • You must pick a single managing resource (the resource that exposes add/remove); the other resource is the associated/subordinate resource.

Implementation
#

  • Naming convention: Add<ManagingResource><AssociatedResource> and Remove<ManagingResource><AssociatedResource>.

    • Example: AddGroupUser / RemoveGroupUser when Group manages users.
  • Requests contain the parent (managing) resource and the identifier of the associated resource (not the full resource).

  • HTTP mapping examples:

POST /groups/1/users:add    { "userId": "users/1" }
POST /groups/1/users:remove { "userId": "users/1" }

Listing associated resources
#

  • Provide two list methods (one per direction) using implicit subcollections:

    • ListGroupUsers({ parent: "groups/1" })GET /groups/1/users
    • ListUserGroups({ parent: "users/1" })GET /users/1/groups
  • These support pagination, filtering, etc., like standard list endpoints.

Data integrity
#

  • Duplicate-add attempts: treat like creating a duplicate resource → return 409 Conflict.
  • Removing a non-member: treat like deleting a non-existent resource → return 412 Precondition Failed (or another appropriate error signaling failed assumption).
  • For clients whose only goal is existence, a success or a 409 Conflict both indicate the association exists.

Final API (essence)
#

  • Minimal API surface: GetUser, GetGroup, AddGroupUser, RemoveGroupUser, ListGroupUsers, ListUserGroups.
  • Resource interfaces keep lists out of-line (e.g., Group may expose userCount but not inline user list).

Trade-offs
#

  • Nonreciprocal relationship: must choose one managing resource (API is asymmetric).
  • No relationship metadata: cannot store attributes tied to the association (join date, role, etc.). If metadata is required, use an explicit association resource instead.

Exercises (core answers)
#

  • Use add/remove when you only need to track existence and want a lightweight API.
  • For Recipe / Ingredient, Recipe is the natural managing resource; method to list ingredients: ListRecipeIngredientsGET /recipes/{id}/ingredients.
  • Duplicate add should result in 409 Conflict (or be interpreted by caller as “already present”).

Takeaway
#

  • The add/remove pattern is a simple, pragmatic way to manage many-to-many relationships when you can accept asymmetry and give up relationship-specific metadata.