Dealing with a “there can only be one” attribute

Hi!
I’ve got a resource of type payment-method with attribute default. If I PATCH a payment method to be default: true, then all other payment methods that belong to that user become default: false. There can only be one default payment method per user.

I’m struggling with the response from that PATCH. Do I only respond with the specific record I requested to change, or do I return all of the affected payment methods?

Responding with only the specific record PATCHed seems logical, but then consumers of the API have to know that piece of business logic. Right now the app that uses this endpoint just does a GET for all of the user’s payment methods immediately after PATCHing any of them.

I’m dealing with the exact same problem and would also love some advice. Someone else on my team suggested changing my API so that the equivalent to your user resource has a default_payment_method relationship. You would then update a payment method to be the default by updating the relationship on the user resource to point to that payment method.

The backend logic and way that you store payment methods could remain the same in terms of having a default: true on the payment methods, but the API could just expose it differently so that implicit “there can only be one” logic would be clearer to clients. However, I’m not sure whether this is the best way to go or not, or whether it works for your use case.

If we stick to the specification :

If a server accepts an update but also changes the resource(s) in ways other
than those specified by the request (for example, updating the updated-at
attribute or a computed sha), it MUST return a 200 OK response. The
response document MUST include a representation of the updated
resource(s) as if a GET request was made to the request URL.

You should return the same result for your PATCH than for the GET on this resource, so you can’t return all the affected payment methods (except if they can be in the included maybe ?).

I like the suggestion of @speterson14 to explicitly give the default payment method in a user relationship.
In this case, you could change the default payment method by PATCHing the relationship and not the payment-method resource.
If we take the consumer point of view, I think this default attribute is more a type of relationship between the user and the payment method than a property owned by the payment method.

@speterson14 we successfully used your suggestion to make a relationship between the user and the default payment method. That fit exactly what we needed to do, while staying within the bounds of the spec @yves mentioned. Thanks y’all!