One of the things I like to think about in these types of situations is, "what 
is good rest api
design".  Nesting resources under other resources is a necessary part of good 
api design, and has
its place.  To borrow some terms from domain driven development:

Collections of objects are called aggregates.  Think 'an order and its line 
items'.  Line items make
no sense without having the order context, so they are an aggregate that is 
accessed under an
Order.  This is called the aggregate root.  The rest api design for such an 
object, using order as
the aggregate root, would look like:

'/orders/' -- all orders
'/orders/{order_key}/' -- a specific order with key.
'/orders/{order_key}/items/' -- All of the order's items.
'/orders/{order_key}/items/{item_key}/' -- a specific line item of the order

When it comes to order items themselves, it isn't helpful to start with them as 
their own aggregate
root in one large collection:

'/items/'   -- all order items in the system

Because you lose the order context. Based on api design, this endpoint will 
need to respond with all
order items across all orders and resort to parameter filtering to provide the 
context you need.

A quote borrowed from Martin Fowler [0]

"An aggregate will have one of its component objects be the aggregate root. Any 
references from
outside the aggregate should only go to the aggregate root. The root can thus 
ensure the integrity
of the aggregate as a whole."

Publishers, importers, and publications are all aggregates that don't make much 
sense outside of
their aggregate root of Repository.  They are dependent on the Repository 
context, and from a domain
view, should be accessed starting with their specific Repository endpoint.

--------------------------------------------------------------
Specific items rebuttals:
    
    Yes, using the primary key uuid's as the immutable key adds some human 
readable challenges to
the API.  That sounds more like a point to discuss in the human readable vs. 
not human readable
immutable key debate.
    
    One of the challenges in software engineering is ensuring the tools you are 
using don't limit
your choices.  DRF limited the choices for pulp's rest API design, and 
drf-nested-routers was
introduced to help remove that limit.  If working around these limitations is 
complex, take
advantage of open source here and help improve the upstream dependencies for 
your workflow.
    
    As far as making things simpler for plugin writers, perhaps there are ways 
you can simplify it
for them by providing some encapsulation in pulp's core instead.  Abstract away 
the nasty bits
behind the scenes, and provide them with a simpler interface to do what they 
need.
    
    With respect to the invested time already in making this work, I agree with 
jeremy that it
should be considered part of the sunken cost fallacy.  What does need to be 
evaluated though is how
much time re-architecting at this point will cost you (discussion, planning, 
and development) vs the
amount of time it will save, and weigh that against any planned milestones for 
pulp to see if it
will push them out as well.
    
    I'm also in agreement that it is moot if pulp3 has a different api 
structure than pulp2.  Major
version boundaries are the perfect time for evaluating and moving such things 
around.

[0] https://martinfowler.com/bliki/DDD_Aggregate.html

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Pulp-dev mailing list
Pulp-dev@redhat.com
https://www.redhat.com/mailman/listinfo/pulp-dev

Reply via email to