Yet another mixed collection question

34 views
Skip to first unread message

Pedro Prieto

unread,
May 26, 2015, 1:06:48 PM5/26/15
to collect...@googlegroups.com
Hi all,

This is my first post in this group. I am currently designing an API with CJ and I have been reading other posts related to subcollections and the like. I think I have understood the basics and the flexibility it provides.

However, I have some doubts about some specific aspects of my implementation, especially the ones related with individual items inside an assorted collection. Please, excuse me if this has already been addressed in other posts.

Let's assume this scenario: a list of companies and a list of visits to each of those companies. A user can do CRUD operations to companies and visits. The collection would be like this one:

{
  "collection": {
    "version": "1.0",
    "href": "/companies",
    "items": [
      {
        "href": "/companies/1",
        "data": [
            {"name": "kind", "value": "company"},
            {"name": "name", "value": "My company"}
        ],
        "links": [
            {"rel": "template", "name": "add_visit", "href": "/companies/1/visits"}
        ]
      },
      {
        "href": "/companies/1/visits/1",
        "data": [
            {"name": "kind", "value": "visit"},
            {"name": "date", "value": "2015/01/01"},
            {"name": "purpose", "value": "Visit no 1."}
        ]
      },
      {
        "href": "/companies/1/visits/2",
        "data": [
            {"name": "kind", "value": "visit"},
            {"name": "date", "value": "2015/01/05"},
            {"name": "purpose", "value": "Visit no 2."}
        ]
      },
      {
        "href": "/companies/2",
        "data": [
            {"name": "kind", "value": "company"},
            {"name": "name", "value": "Another company"}
        ],
        "links": [
            {"rel": "template", "name": "add_visit", "href": "/companies/2/visits"}
        ]
      },
      {
        "href": "/companies/2/visits/1",
        "data": [
            {"name": "kind", "value": "visit"},
            {"name": "date", "value": "2015/05/01"},
            {"name": "purpose", "value": "Visit no 1."}
        ]
      }
    ],
    "template": {
       "data": [
            {"name": "name", "value": ""}
      ]
    }
  }
}


I have used the template in the collection to create companies. To create visits, I use a link in each company item that points to a template representation.

And finally, my questions:

1) Does this approach meet CJ requirements? Do I need to include the link to the template in each item or should I include a simple link to /companies/X/visits and then leave the clients the option to do a POST request to it? What I am trying to accomplish with that link is the option to create visits from the collection directly.

2) I a bit lost with the concept collection vs item. I know both are represented with a collection object, but the spec says that an item representation contains only one item in the "items" array. So, in this example, if I want to represent a company and its associated visits as an item representation, how should I do it? I have thought of four options:

  a) Create a new link in each "company" item that points to a new collection. Something like:

      {
        "href": "/companies/1",
        "data": [
            {"name": "kind", "value": "company"},
            {"name": "name", "value": "My company"}
        ],
        "links": [
            {"rel": "template", "name": "add_visit", "href": "/companies/1/visits"},
            {"rel": "collection", "name": "individual_company", "href": "/companies/1/full_data"}
        ]
      }


     With this approach, the new collection would allow the creation of more visits (as it is a collection, it allows POST requests) and it could also display more detailed data than in the original collection.

  b) Create a new link in each "company" item that points to a query to the actual collection. Something like:

      {
        "href": "/companies/1",
        ...
        "links": [
           {"rel": "template", "name": "add_visit", "href": "/companies/1/visits"},
           {"rel": "collection", "name": "individual_company", "href": "/companies?id=1"}
         ]
      }


     With this approach the data display for that company would be the same showed in the original collection. So, I would have to display all data in the original collection.

  c) Create a new link in each "company" item that points to the item url of that company:

      {
        "href": "/companies/1",
        ...
        "links": [
           {"rel": "template", "name": "add_visit", "href": "/companies/1/visits"},
           {"rel": "collection", "name": "individual_company", "href": "/companies/1"}
        ]
      }


     I mean, the same option than a) but with the url of the company item. Is this possible? I mean, that URL would act as a collection (allow POST) and item (allow PUT) url.

  d) Flatten the hierachy and return an item with the flattened properties of companies and visits.

Is there a "better" way than these four? (I know there is no "right" and absolute way to do things, but I mean "more elegant" or "simpler").

3) Lastly, when deleting a company item, all its associated visits would be deleted as well. Should the server tell clients about that? Or only return 204?

Thanks in advance. I think CJ is really cool, BTW.

Regards,

Pedro Prieto

mca

unread,
May 26, 2015, 1:43:03 PM5/26/15
to collect...@googlegroups.com
Pedro:

good to see you here on the list.

not sure i follow all your local constraints, but here's my feedback.

a) the _simplest_ approach to dealing with nested sets of data (company==parent, visits==children) is to represent each company as an item with a link that that points to the visits for that company. IOW, don't do a heterogeneous representation, just use links from one collection to the other.

b) if you _do_ decide to represent both a parent (company) and the children (visits) in a single representation, just know that generic clients are likely NOT going to render them in any visual or related way -- you're going to need to write a bespoke client for that.

having said that...

1) yes, your representation seems to be a valid Cj response. i can't know for sure if it allows/prevents all the operations you want since i don't know your API details. right now it allows managing the company collection (add, edit, delete) using the inline template.

2) you are not REQUIRED to return only one "item" when you resolve a company item URL (/companies/1). you can have as many items there as you like. generic Cj clients won't "know" this is an item URL, they just "know" it's a URL and a Cj representation will be the response. feel free to design the representation to match your needs.

the following material in your post is hard for me to follow (a-d). my advice at this point would be to just say you can use templates inline or as links (keep in mind generic clients will resolve the template link and will expect a Cj response back with a template object for use in adding/editing an item. when i return "naked" templates like this, i usually fill in the values if it is an edit (rel:"template edit") and leave the values blank when the action is an add (rel:"template create-form").

not sure if that helps, but it's what i have right now.

3) you're free to send responses for delete actions that contain whatever information you wish. you can even send a response do a delete action that is a representation of a template asking the client app to confirm the delete:

template: {
  data[{"name" : "confirm", "value":"", "prompt": "Enter 'yes' to delete this company and all associated visits"}
 ]
}

hope this helps and looking forward to hearing more about what you're working on and how Cj is working out for you.

cheers.


--
You received this message because you are subscribed to the Google Groups "Collection+JSON" group.
To unsubscribe from this group and stop receiving emails from it, send an email to collectionjso...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Pedro Prieto

unread,
May 26, 2015, 3:44:45 PM5/26/15
to collect...@googlegroups.com
Thank you for your quick feedback, Mike.

I wanted to provide all data (company + visits) in the same response. I know generic clients will not show the relations between items, but I want to avoid sending two requests each time.

Thank you for your clarification about collection vs items urls. So, if I understand it correctly, a collection URL can be the same as the item URL of another collection.

And thanks for the last suggestion about delete confirmation. I hadn't thought of that. Very useful!

Regards.

Carles Jove i Buxeda

unread,
May 27, 2015, 1:04:19 AM5/27/15
to collect...@googlegroups.com
Pedro, I don't know if you're familiar with Cj extensions. A while ago there was some discussion in this forum about representing associated items, and the inline extension came out of this. It lets you have nested Cj under an inline object, and reference them through item.links With this extension you're representing some links inline, to avoid having to make an extra request to the server.

Check it out, I think it might help you :-)

Pedro Prieto

unread,
May 27, 2015, 2:33:15 AM5/27/15
to collect...@googlegroups.com
Thank you, Carles. Yes, I am aware of them. I had already checked that out but I opted for the mixed collections approach.
Reply all
Reply to author
Forward
0 new messages