I’m implementing the json-api spec for an internal application API with a pretty granular rights/permissions system and my team has been debating various way to handle the case when some users don’t have access to read certain fields from an endpoint.
Here’s a quick example:
- A store has a name, net revenue, and employees.
- An employee of the store can see the name and other employees, but not the net revenue.
- A manager of the store can see name, employees, and net revenue (via a
read_store_net_revenue
permission)
When an employee accesses the /api/stores/1
endpoint, we don’t want to disclose the value of the net revenue (and honestly, probably don’t even want to expose the presence of that field). We weren’t able to identify anything in the spec addressing the delivery of conditional attributes, so wanted see if we either a) missed it, or b) its purposely not defined and thus curious if anyone has implemented something similar.
After some debate, we’ve arrived at two approaches:
- Simply don’t return the net revenue field inside of the attributes when employees without the
read_net_revenue
permission requestsapi/stores/1
. The con here is that knowing what is and isn’t restricted is somewhat of a mystery in the schema without adding additional information not defined in the spec. - Make the inclusion of the net revenue field always opt-in, e.g.
/api/stores/1?include=net_revenue
. We’d use include and treat restricted attributes as relations to leverage the existing work that’s happening there, to raise a proper error messages if a field was requested to which the user doesn’t have access, and to make it explicit that the requested attribute isn’t always available. The major con here is endpoint bloat, as we could end up with 10-15+ end points per model (eg store, store-net-revenue, store-net-profit, etc…).
Thanks for your help!