<div dir="ltr"><div>Personally, I believe that a hierarchical structure makes sense in our API design. </div><div><br></div><div>Importers/Publishers are unique to a repository, they cannot switch their repository parent, and they cannot exist without a repository. When a repository is deleted, its related importers and publisher are deleted as well, as they are meaningless without the context of the parent Repository. </div><div><br></div><div>I think a lot of URL design issues can be resolved by having better filters like:</div><div>    GET /api/v1/people/?item_name=Concentrated%20Sprayflesh</div><div>Not necessarily by allowing users to work with items directly (you might want that for other reasons, but for not for getting all the user with sprayflesh in their inventory, because I don't think exposing the user-item join table in /items/1/ makes a lot of sense.)</div><div><br></div><div>I think as far as pulp3 goes, as long as we provide good filter support we can meet all of a user's needs. I did find a library that support relationship filters through drf: <a href="https://github.com/philipn/django-rest-framework-filters">https://github.com/philipn/django-rest-framework-filters</a> that might be viable to pull in (Open Source FTW!)</div><div><br></div><div>Our initial reasoning for switching from naturals keys in URLs to pk instead of making natural keys immutable was that URLs do not need to be human friendly and pretty. Perhaps we should revisit that decision if human readable urls are our goal.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 17, 2017 at 9:55 AM, Patrick Creech <span dir="ltr"><<a href="mailto:pcreech@redhat.com" target="_blank">pcreech@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">One of the things I like to think about in these types of situations is, "what is good rest api<br>
design".  Nesting resources under other resources is a necessary part of good api design, and has<br>
its place.  To borrow some terms from domain driven development:<br>
<br>
Collections of objects are called aggregates.  Think 'an order and its line items'.  Line items make<br>
no sense without having the order context, so they are an aggregate that is accessed under an<br>
Order.  This is called the aggregate root.  The rest api design for such an object, using order as<br>
the aggregate root, would look like:<br>
<br>
'/orders/' -- all orders<br>
'/orders/{order_key}/' -- a specific order with key.<br>
'/orders/{order_key}/items/' -- All of the order's items.<br>
'/orders/{order_key}/items/{<wbr>item_key}/' -- a specific line item of the order<br>
<br>
When it comes to order items themselves, it isn't helpful to start with them as their own aggregate<br>
root in one large collection:<br>
<br>
'/items/'   -- all order items in the system<br>
<br>
Because you lose the order context. Based on api design, this endpoint will need to respond with all<br>
order items across all orders and resort to parameter filtering to provide the context you need.<br>
<br>
A quote borrowed from Martin Fowler [0]<br>
<br>
"An aggregate will have one of its component objects be the aggregate root. Any references from<br>
outside the aggregate should only go to the aggregate root. The root can thus ensure the integrity<br>
of the aggregate as a whole."<br>
<br>
Publishers, importers, and publications are all aggregates that don't make much sense outside of<br>
their aggregate root of Repository.  They are dependent on the Repository context, and from a domain<br>
view, should be accessed starting with their specific Repository endpoint.<br>
<br>
------------------------------<wbr>------------------------------<wbr>--<br>
Specific items rebuttals:<br>
<br>
    Yes, using the primary key uuid's as the immutable key adds some human readable challenges to<br>
the API.  That sounds more like a point to discuss in the human readable vs. not human readable<br>
immutable key debate.<br>
<br>
    One of the challenges in software engineering is ensuring the tools you are using don't limit<br>
your choices.  DRF limited the choices for pulp's rest API design, and drf-nested-routers was<br>
introduced to help remove that limit.  If working around these limitations is complex, take<br>
advantage of open source here and help improve the upstream dependencies for your workflow.<br>
<br>
    As far as making things simpler for plugin writers, perhaps there are ways you can simplify it<br>
for them by providing some encapsulation in pulp's core instead.  Abstract away the nasty bits<br>
behind the scenes, and provide them with a simpler interface to do what they need.<br>
<br>
    With respect to the invested time already in making this work, I agree with jeremy that it<br>
should be considered part of the sunken cost fallacy.  What does need to be evaluated though is how<br>
much time re-architecting at this point will cost you (discussion, planning, and development) vs the<br>
amount of time it will save, and weigh that against any planned milestones for pulp to see if it<br>
will push them out as well.<br>
<br>
    I'm also in agreement that it is moot if pulp3 has a different api structure than pulp2.  Major<br>
version boundaries are the perfect time for evaluating and moving such things around.<br>
<br>
[0] <a href="https://martinfowler.com/bliki/DDD_Aggregate.html" rel="noreferrer" target="_blank">https://martinfowler.com/<wbr>bliki/DDD_Aggregate.html</a><br>______________________________<wbr>_________________<br>
Pulp-dev mailing list<br>
<a href="mailto:Pulp-dev@redhat.com">Pulp-dev@redhat.com</a><br>
<a href="https://www.redhat.com/mailman/listinfo/pulp-dev" rel="noreferrer" target="_blank">https://www.redhat.com/<wbr>mailman/listinfo/pulp-dev</a><br>
<br></blockquote></div><br></div>