JSON API v2 conventions discussion

I've been reading how different API clients prefer different JSON responses and that there is no standard "convention over configuration". For example, Ember.js prefers the _ids as an array in the root node, whereas other JS clients prefers to transverse the id's in the child nodes. (see ex. below)

My questions:

  1. Is there a particular API JSON convention that the Foreman Hammer CLI prefers?
  2. Is Katello consuming the Foreman API or plan to in the future?
  3. Is Foreman consuming the Katello API or plan to in the future?
  4. Are the Katello API and Foreman API v1 conventions similar or different?
  5. What other JSON clients / frameworks do we know about that are big consumers of Foreman API

Here is an example of side-loaded relationships from the Ember.js documetation.

http://emberjs.com/guides/models/the-rest-adapter/#toc_sideloaded-relationships

··· --- To reduce the number of HTTP requests necessary, you can sideload additional records in your JSON response. Sideloaded records live outside the JSON root, and are represented as an array of hashes:

{
“post”: {
“id”: 1,
“title”: “Rails is omakase”,
“comment_ids”: [1, 2, 3]
},

“comments”: [{
“id”: 1,
“body”: “But is it lightweight omakase?”
},
{
“id”: 2,
“body”: “I for one welcome our new omakase overlords”
},
{
“id”: 3,
“body”: “Put me on the fast track to a delicious dinner”
}]
}

Regards,

Joseph

I think it would be interesting to see this done together with your work
API more RESTful (couldn't find the PR?).
-d

··· On Wed, Jul 10, 2013 at 7:41 AM, Joseph Magen wrote:

I’ve been reading how different API clients prefer different JSON
responses and that there is no standard “convention over configuration”.
For example, Ember.js prefers the _ids as an array in the root node,
whereas other JS clients prefers to transverse the id’s in the child nodes.
(see ex. below)

My questions:

  1. Is there a particular API JSON convention that the Foreman Hammer CLI
    prefers?
  2. Is Katello consuming the Foreman API or plan to in the future?
  3. Is Foreman consuming the Katello API or plan to in the future?
  4. Are the Katello API and Foreman API v1 conventions similar or different?
  5. What other JSON clients / frameworks do we know about that are big
    consumers of Foreman API

Here is an example of side-loaded relationships from the Ember.js
documetation.

http://emberjs.com/guides/models/the-rest-adapter/#toc_sideloaded-relationships


To reduce the number of HTTP requests necessary, you can sideload
additional records in your JSON response. Sideloaded records live outside
the JSON root, and are represented as an array of hashes:

{
“post”: {
“id”: 1,
“title”: “Rails is omakase”,
“comment_ids”: [1, 2, 3]
},

“comments”: [{
“id”: 1,
“body”: “But is it lightweight omakase?”
},
{
“id”: 2,
“body”: “I for one welcome our new omakase overlords”
},
{
“id”: 3,
“body”: “Put me on the fast track to a delicious dinner”
}]
}

Regards,

Joseph


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

> I personally prefer traversing the ids in the child nodes.
>
> What does putting the _ids in an array in the root node give you?
> Wouldn't you still need to link each individual post/comment to the _ids
> array?
>
> As far as "sideloading" goes, I guess it all comes down to a balance of
> TMI and reducing HTTP requests. I tend to be more on the side of reducing
> requests since that is likely where most of the application's latency is.
>
> I would change your example to look like this:
>
> GET /posts/
>
> {
> "total": 10,
> "limit": 2,
> "offset" 3,
> "results": [
>

I think the lines above are an important point that needs to be taken into
consideration up front. There is metadata around an API request that can be
important to a user making a basic API call or an interface such as our
GUI's. We have been doing a lot more integration of our GUI with our API on
the Katello side lately and the things we've found missing are:

  • paging
  • total records
  • subtotal of records based upon query
  • offset within the collection
  • knowing if there is a verbose version of the dataset

As someone mentioned, predictability is also a nice feature. Knowing that
if I query a resource and the records are stored at response['records']
allows me to generalize and write predictable interfaces.

··· On Wed, Jul 10, 2013 at 2:52 PM, Walden Raines wrote:
    {
        "id": 1,
        "title": "Rails is omakase",
        "comments": [
            {
                "id": 1,
                "body": "But is it _lightweight_ omakase?"
            },
            {
                "id": 2,
                "body": "I for one welcome our new omakase overlords"
            },
            {
                "id": 3,
                "body": "Put me on the fast track to a delicious

dinner"
}
]
},
{
“id”: 2,
“title”: “Rails is omakase”,
“comments”: [
{
“id”: 5,
“body”: “But is it lightweight omakase?”
},
{
“id”: 6,
“body”: “I for one welcome our new omakase overlords”
},
{
“id”: 10,
“body”: “Put me on the fast track to a delicious
dinner”
}
]
}
]
}

And the individual GET to /post/:id would return one of those hashes in
the results array. To me, a comment is a sub-resource of a post (I’m
making the assumption that a comment cannot exist without a post).

For what it’s worth, I’ve used Ember.js at a past company and I am not a
fan. It seemed convoluted, poorly documented, and slow (though to be fair,
it wasn’t yet 1.0 when we were using it).

AngularJS, on the other hand, is straightforward, well documented, and
fast.

Cheers,
Walden

----- Original Message -----
From: “Joseph Magen” jmagen@redhat.com
To: “foreman-dev” foreman-dev@googlegroups.com, katello-devel@redhat.com
Sent: Wednesday, July 10, 2013 2:41:12 AM
Subject: [katello-devel] JSON API v2 conventions discussion

I’ve been reading how different API clients prefer different JSON
responses and that there is no standard “convention over configuration”.
For example, Ember.js prefers the _ids as an array in the root node,
whereas other JS clients prefers to transverse the id’s in the child nodes.
(see ex. below)

My questions:

  1. Is there a particular API JSON convention that the Foreman Hammer CLI
    prefers?
  2. Is Katello consuming the Foreman API or plan to in the future?
  3. Is Foreman consuming the Katello API or plan to in the future?
  4. Are the Katello API and Foreman API v1 conventions similar or different?
  5. What other JSON clients / frameworks do we know about that are big
    consumers of Foreman API

Here is an example of side-loaded relationships from the Ember.js
documetation.

http://emberjs.com/guides/models/the-rest-adapter/#toc_sideloaded-relationships


To reduce the number of HTTP requests necessary, you can sideload
additional records in your JSON response. Sideloaded records live outside
the JSON root, and are represented as an array of hashes:

{
“post”: {
“id”: 1,
“title”: “Rails is omakase”,
“comment_ids”: [1, 2, 3]
},

“comments”: [{
“id”: 1,
“body”: “But is it lightweight omakase?”
},
{
“id”: 2,
“body”: “I for one welcome our new omakase overlords”
},
{
“id”: 3,
“body”: “Put me on the fast track to a delicious dinner”
}]
}

Regards,

Joseph


katello-devel mailing list
katello-devel@redhat.com
https://www.redhat.com/mailman/listinfo/katello-devel


katello-devel mailing list
katello-devel@redhat.com
https://www.redhat.com/mailman/listinfo/katello-devel

> I personally prefer traversing the ids in the child nodes.
>
> What does putting the _ids in an array in the root node give you? Wouldn't you still need to link each individual post/comment to the _ids array?

I like the first example with "comment_ids": [1, 2, 3]. It's more
general and it avoids data duplicity when side-loading.

E.g. list of posts with side loaded authors

{
"posts": [
{
"id": 1,
"title": "Ruby tutorial",
"author_id": 1
},
{
"id": 2,
"title": "Rails tutorial",
"author_id": 1
},
{
"id": 3,
"title": "Haskell tutorial",
"author_id": 2
}
],

"authors": [
{
"id": 1,
"name": "John"
},
{
"id": 2,
"name": "Steve"
}
]
}

It works for any number of side-loaded associations e.g. list of posts
with side loaded comments and authors.

{
"posts": [
{
"id": 1,
"title": "Ruby tutorial",
"author_id": 1,
"comments_ids": [1, 2]
},
{
"id": 2,
"title": "Rails tutorial",
"author_id": 1,
"comments_ids": [3]
},
{
"id": 3,
"title": "Haskell tutorial",
"author_id": 2,
"comments_ids": []
}
],

"authors": [
{
"id": 1,
"name": "John"
},
{
"id": 2,
"name": "Steve"
}
],

"comments": [
{
"id": 1,
"body": "…",
"author_id": 1
},
{
"id": 2,
"body": "…",
"author_id": 2
},
{
"id": 3,
"body": "…",
"author_id": 1
}
]
}

··· On 10.07.13 20:52, Walden Raines wrote:

As far as “sideloading” goes, I guess it all comes down to a balance of TMI and reducing HTTP requests. I tend to be more on the side of reducing requests since that is likely where most of the application’s latency is.

I would change your example to look like this:

GET /posts/

{
“total”: 10,
“limit”: 2,
“offset” 3,
“results”: [
{
“id”: 1,
“title”: “Rails is omakase”,
“comments”: [
{
“id”: 1,
“body”: “But is it lightweight omakase?”
},
{
“id”: 2,
“body”: “I for one welcome our new omakase overlords”
},
{
“id”: 3,
“body”: “Put me on the fast track to a delicious dinner”
}
]
},
{
“id”: 2,
“title”: “Rails is omakase”,
“comments”: [
{
“id”: 5,
“body”: “But is it lightweight omakase?”
},
{
“id”: 6,
“body”: “I for one welcome our new omakase overlords”
},
{
“id”: 10,
“body”: “Put me on the fast track to a delicious dinner”
}
]
}
]
}

And the individual GET to /post/:id would return one of those hashes in the results array. To me, a comment is a sub-resource of a post (I’m making the assumption that a comment cannot exist without a post).

For what it’s worth, I’ve used Ember.js at a past company and I am not a fan. It seemed convoluted, poorly documented, and slow (though to be fair, it wasn’t yet 1.0 when we were using it).

AngularJS, on the other hand, is straightforward, well documented, and fast.

Cheers,
Walden

----- Original Message -----
From: “Joseph Magen” jmagen@redhat.com
To: “foreman-dev” foreman-dev@googlegroups.com, katello-devel@redhat.com
Sent: Wednesday, July 10, 2013 2:41:12 AM
Subject: [katello-devel] JSON API v2 conventions discussion

I’ve been reading how different API clients prefer different JSON responses and that there is no standard “convention over configuration”. For example, Ember.js prefers the _ids as an array in the root node, whereas other JS clients prefers to transverse the id’s in the child nodes. (see ex. below)

My questions:

  1. Is there a particular API JSON convention that the Foreman Hammer CLI prefers?
  2. Is Katello consuming the Foreman API or plan to in the future?
  3. Is Foreman consuming the Katello API or plan to in the future?
  4. Are the Katello API and Foreman API v1 conventions similar or different?
  5. What other JSON clients / frameworks do we know about that are big consumers of Foreman API

Here is an example of side-loaded relationships from the Ember.js documetation.

http://emberjs.com/guides/models/the-rest-adapter/#toc_sideloaded-relationships


To reduce the number of HTTP requests necessary, you can sideload additional records in your JSON response. Sideloaded records live outside the JSON root, and are represented as an array of hashes:

{
“post”: {
“id”: 1,
“title”: “Rails is omakase”,
“comment_ids”: [1, 2, 3]
},

“comments”: [{
“id”: 1,
“body”: “But is it lightweight omakase?”
},
{
“id”: 2,
“body”: “I for one welcome our new omakase overlords”
},
{
“id”: 3,
“body”: “Put me on the fast track to a delicious dinner”
}]
}

Regards,

Joseph


katello-devel mailing list
katello-devel@redhat.com
https://www.redhat.com/mailman/listinfo/katello-devel


katello-devel mailing list
katello-devel@redhat.com
https://www.redhat.com/mailman/listinfo/katello-devel

>> I've been reading how different API clients prefer different JSON
>> responses and that there is no standard "convention over
>> configuration". For example, Ember.js prefers the _ids as an array in
>> the root node, whereas other JS clients prefers to transverse the id's
>> in the child nodes. (see ex. below)
>>
>> My questions:
>> 1) Is there a particular API JSON convention that the Foreman Hammer
>> CLI prefers?
> Hammer does not have any preferences in this. We use own tool for
> transformation of the data in json responses which is pretty flexible.
> The current conventions work for us well.
>> 2) Is Katello consuming the Foreman API or plan to in the future?
>> 3) Is Foreman consuming the Katello API or plan to in the future?
>> 4) Are the Katello API and Foreman API v1 conventions similar or
>> different?
> In Katello API v1 conventions are inconsistent. That is why we created
> API v2 where we tried to stick to Foreman API conventions as much as
> possible.
>> 5) What other JSON clients / frameworks do we know about that are big
>> consumers of Foreman API
>>
>> Here is an example of side-loaded relationships from the Ember.js
>> documetation.
>>
>> http://emberjs.com/guides/models/the-rest-adapter/#toc_sideloaded-relationships
>>
>>
>> —
>> To reduce the number of HTTP requests necessary, you can sideload
>> additional records in your JSON response. Sideloaded records live
>> outside the JSON root, and are represented as an array of hashes:
>>
>> {
>> "post": {
>> "id": 1,
>> "title": "Rails is omakase",
>> "comment_ids": [1, 2, 3]
>> },
>>
>> "comments": [{
>> "id": 1,
>> "body": "But is it lightweight omakase?"
>> },
>> {
>> "id": 2,
>> "body": "I for one welcome our new omakase overlords"
>> },
>> {
>> "id": 3,
>> "body": "Put me on the fast track to a delicious dinner"
>> }]
>> }
>> —
> If we need to reduce requests I would prefere nesting of resources. From
> the restful interface I would somehow expect to get a post if ask for
> post, nothing more. So my preferred response would look like this (or at
> least that is what we do in Katello API when it makes sense):
> —
> {
> "post": {
> "id": 1,
> "title": "Rails is omakase",
> "comments": [{
> "comment": {
> "id": 1,
> "body": "But is it lightweight omakase?"
> }
> },
> {
> "comment": {
> "id": 2,
> "body": "I for one welcome our new omakase overlords"
> }
> },
> {
> "comment": {
> "id": 3,
> "body": "Put me on the fast track to a delicious dinner"
> }
> }]
> },
> }
> —
>

This nesting works very well with current cli implementation. It's the
simplest way. On the other hand it brings redundancy.

I like the idea of side loading. It solves the problem with loading
related resources effectively. So +1 for that. Maybe we can make it
optional.

Another solution can be to enable scoped search by ids. Then you could
load all related comments with one search request (per resource type).
We will probably need to enable this anyway. We have to translate
name->id when associating resources in the cli.

T.

··· On 07/11/2013 08:06 PM, Martin Bacovsky wrote: > On 07/10/2013 08:41 AM, Joseph Magen wrote:

Regards,
Martin

Regards,

Joseph


katello-devel mailing list
katello-devel@redhat.com
https://www.redhat.com/mailman/listinfo/katello-devel


katello-devel mailing list
katello-devel@redhat.com
https://www.redhat.com/mailman/listinfo/katello-devel

A side note - "foreman-dev" is missing some of the replies - I don't think
everybody is either subscribed to this list?

I don't like side loading at all - It derails discoverability of REST api,
as it assumes apriori knowledge of associations between the resource and
its sub-resources. Including extended (full?) data in sub-resource
collections has the same benefits as side loading and still allows for
discoverability. It looks like it might be useful to be able to switch
between inline and normal REST representation (href + relations) of
sub-resource collections though, perhaps using a query parameter?

It's true that inlining of sub-resources results in redundant bits of data,
but we wouldn't be using ASCII-based protocol if we were that concerned
with the throughput. There is also an option of using http compression if
that becomes a concern.

I'm somewhat on the fence regarding including of db cursor-type metadata
for replies that return lists of resources (on the root level). It is nice
to have as little state as possible on the server however, and for the
client-side cursor to work we'd need to include the total number of
resources (at the very least) in the reply.
-d

··· On Thu, Jul 11, 2013 at 8:17 AM, Petr Chalupa wrote:

On 10.07.13 20:52, Walden Raines wrote:

I personally prefer traversing the ids in the child nodes.

What does putting the _ids in an array in the root node give you?
Wouldn’t you still need to link each individual post/comment to the _ids
array?

I like the first example with "comment_ids": [1, 2, 3]. It’s more
general and it avoids data duplicity when side-loading.

E.g. list of posts with side loaded authors

{
“posts”: [
{
“id”: 1,
“title”: “Ruby tutorial”,
“author_id”: 1
},
{
“id”: 2,
“title”: “Rails tutorial”,
“author_id”: 1
},
{
“id”: 3,
“title”: “Haskell tutorial”,
“author_id”: 2
}
],

“authors”: [
{
“id”: 1,
“name”: “John”
},
{
“id”: 2,
“name”: “Steve”
}
]
}

It works for any number of side-loaded associations e.g. list of posts
with side loaded comments and authors.

{
“posts”: [
{
“id”: 1,
“title”: “Ruby tutorial”,
“author_id”: 1,
“comments_ids”: [1, 2]
},
{
“id”: 2,
“title”: “Rails tutorial”,
“author_id”: 1,
“comments_ids”: [3]
},
{
“id”: 3,
“title”: “Haskell tutorial”,
“author_id”: 2,
“comments_ids”: []
}
],

“authors”: [
{
“id”: 1,
“name”: “John”
},
{
“id”: 2,
“name”: “Steve”
}
],

“comments”: [
{
“id”: 1,
“body”: “…”,
“author_id”: 1
},
{
“id”: 2,
“body”: “…”,
“author_id”: 2
},
{
“id”: 3,
“body”: “…”,
“author_id”: 1
}
]
}

As far as “sideloading” goes, I guess it all comes down to a balance of
TMI and reducing HTTP requests. I tend to be more on the side of reducing
requests since that is likely where most of the application’s latency is.

I would change your example to look like this:

GET /posts/

{
“total”: 10,
“limit”: 2,
“offset” 3,
“results”: [

     {
         "id": 1,
         "title": "Rails is omakase",
         "comments": [
             {
                 "id": 1,
                 "body": "But is it _lightweight_ omakase?"
             },
             {
                 "id": 2,
                 "body": "I for one welcome our new omakase overlords"
             },
             {
                 "id": 3,
                 "body": "Put me on the fast track to a delicious

dinner"
}
]
},

     {
         "id": 2,
         "title": "Rails is omakase",
         "comments": [

             {
                 "id": 5,
                 "body": "But is it _lightweight_ omakase?"
             },
             {
                 "id": 6,
                 "body": "I for one welcome our new omakase overlords"
             },
             {
                 "id": 10,

                 "body": "Put me on the fast track to a delicious

dinner"
}
]
}
]
}

And the individual GET to /post/:id would return one of those hashes in
the results array. To me, a comment is a sub-resource of a post (I’m
making the assumption that a comment cannot exist without a post).

For what it’s worth, I’ve used Ember.js at a past company and I am not a
fan. It seemed convoluted, poorly documented, and slow (though to be fair,
it wasn’t yet 1.0 when we were using it).

AngularJS, on the other hand, is straightforward, well documented, and
fast.

Cheers,
Walden

----- Original Message -----
From: “Joseph Magen” jmagen@redhat.com
To: “foreman-dev” foreman-dev@googlegroups.com**,
katello-devel@redhat.com
Sent: Wednesday, July 10, 2013 2:41:12 AM
Subject: [katello-devel] JSON API v2 conventions discussion

I’ve been reading how different API clients prefer different JSON
responses and that there is no standard “convention over configuration”.
For example, Ember.js prefers the _ids as an array in the root node,
whereas other JS clients prefers to transverse the id’s in the child nodes.
(see ex. below)

My questions:

  1. Is there a particular API JSON convention that the Foreman Hammer CLI
    prefers?
  2. Is Katello consuming the Foreman API or plan to in the future?
  3. Is Foreman consuming the Katello API or plan to in the future?
  4. Are the Katello API and Foreman API v1 conventions similar or
    different?
  5. What other JSON clients / frameworks do we know about that are big
    consumers of Foreman API

Here is an example of side-loaded relationships from the Ember.js
documetation.

http://emberjs.com/guides/models/the-rest-adapter/#toc_
sideloaded-relationshipshttp://emberjs.com/guides/models/the-rest-adapter/#toc_sideloaded-relationships


To reduce the number of HTTP requests necessary, you can sideload
additional records in your JSON response. Sideloaded records live outside
the JSON root, and are represented as an array of hashes:

{
“post”: {
“id”: 1,
“title”: “Rails is omakase”,
“comment_ids”: [1, 2, 3]
},

“comments”: [{
“id”: 1,
“body”: “But is it lightweight omakase?”
},
{
“id”: 2,
“body”: “I for one welcome our new omakase overlords”
},
{
“id”: 3,
“body”: “Put me on the fast track to a delicious dinner”
}]
}

Regards,

Joseph

_____________**
katello-devel mailing list
katello-devel@redhat.com
https://www.redhat.com/**mailman/listinfo/katello-develhttps://www.redhat.com/mailman/listinfo/katello-devel

_____________**
katello-devel mailing list
katello-devel@redhat.com
https://www.redhat.com/**mailman/listinfo/katello-develhttps://www.redhat.com/mailman/listinfo/katello-devel


You received this message because you are subscribed to the Google Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to foreman-dev+unsubscribe@**googlegroups.comforeman-dev%2Bunsubscribe@googlegroups.com
.
For more options, visit https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out
.

Hello,

my (exactly) two cents:

> I don't like side loading at all - It derails discoverability of REST api,
> as it assumes apriori knowledge of associations between the resource and
> its sub-resources. Including extended (full?) data in sub-resource
> collections has the same benefits as side loading and still allows for
> discoverability. It looks like it might be useful to be able to switch
> between inline and normal REST representation (href + relations) of
> sub-resource collections though, perhaps using a query parameter?
+1

> It's true that inlining of sub-resources results in redundant bits of data,
> but we wouldn't be using ASCII-based protocol if we were that concerned
> with the throughput. There is also an option of using http compression if
> that becomes a concern.
+1

··· -- Marek

> A side note - "foreman-dev" is missing some of the replies - I don't
> think everybody is either subscribed to this list?
>
> I don't like side loading at all - It derails discoverability of REST
> api, as it assumes apriori knowledge of associations between the
> resource and its sub-resources. Including extended (full?) data in
> sub-resource collections has the same benefits as side loading and still
> allows for discoverability. It looks like it might be useful to be able
> to switch between inline and normal REST representation (href +
> relations) of sub-resource collections though, perhaps using a query
> parameter?

I think side-loading works with HATEOAS links as well. Side-loaded
objects are not included into the response by default unless client ask
for them via query parameter. The difference is only placement of
additional resources: in-lined vs side-loaded.

> It's true that inlining of sub-resources results in redundant bits of
> data, but we wouldn't be using ASCII-based protocol if we were that
> concerned with the throughput. There is also an option of using http
> compression if that becomes a concern.

Yes I agree for most cases the redundancy won't be big and compression
can also help. I'm concerned about cases with rather dense m:n relations.

E.g. packages and it's dependencies:
With in-lining this response could get quite big. It can be compressed
but it still has to be generated on the server and parsed again on the
client side. Retrieving dependencies package by package would be even
slower.

E.g. previous example with association to architecture:
Architecture would be duplicated a lot - each package in the list and
also in all dependent packages. Compression will help to save the
bandwidth but it still seems to me like a lot of work to generate and to
parse it.

Side-loading should be able to handle similar situations better.

Another way to solve it would probably be to treat dependency
association as a resource. Than the example above could be retrieved
effectively in few steps: packages, then theirs dependencies, missing
packages from the other side of dependency association. But I am not
sure if this is a good idea, it seems wrong to me.

So the question is if there are examples such as described above and if
which they would cause problems with in-lining. If not then I think it
does not matter if in-lining or side-loading is used.

Petr

··· On 12.07.13 12:15, Dmitri Dolguikh wrote:

I’m somewhat on the fence regarding including of db cursor-type metadata
for replies that return lists of resources (on the root level). It is
nice to have as little state as possible on the server however, and for
the client-side cursor to work we’d need to include the total number of
resources (at the very least) in the reply.
-d

On Thu, Jul 11, 2013 at 8:17 AM, Petr Chalupa <pchalupa@redhat.com > mailto:pchalupa@redhat.com> wrote:

On 10.07.13 20:52, Walden Raines wrote:

    I personally prefer traversing the ids in the child nodes.

    What does putting the _ids in an array in the root node give
    you?  Wouldn't you still need to link each individual
    post/comment to the _ids array?


I like the first example with `"comment_ids": [1, 2, 3]`. It's more
general and it avoids data duplicity when side-loading.

E.g. list of posts with side loaded authors

{
   "posts": [
     {
       "id": 1,
       "title": "Ruby tutorial",
       "author_id": 1
     },
     {
       "id": 2,
       "title": "Rails tutorial",
       "author_id": 1
     },
     {
       "id": 3,
       "title": "Haskell tutorial",
       "author_id": 2
     }
   ],

   "authors": [
     {
       "id": 1,
       "name": "John"
     },
     {
       "id": 2,
       "name": "Steve"
     }
   ]
}

It works for any number of side-loaded associations e.g. list of
posts with side loaded comments and authors.

{
   "posts": [
     {
       "id": 1,
       "title": "Ruby tutorial",
       "author_id": 1,
       "comments_ids": [1, 2]
     },
     {
       "id": 2,
       "title": "Rails tutorial",
       "author_id": 1,
       "comments_ids": [3]
     },
     {
       "id": 3,
       "title": "Haskell tutorial",
       "author_id": 2,
       "comments_ids": []
     }
   ],

   "authors": [
     {
       "id": 1,
       "name": "John"
     },
     {
       "id": 2,
       "name": "Steve"
     }
   ],

   "comments": [
     {
       "id": 1,
       "body": "...",
       "author_id": 1
     },
     {
       "id": 2,
       "body": "...",
       "author_id": 2
     },
     {
       "id": 3,
       "body": "...",
       "author_id": 1
     }
   ]
}






    As far as "sideloading" goes, I guess it all comes down to a
    balance of TMI and reducing HTTP requests.  I tend to be more on
    the side of reducing requests since that is likely where most of
    the application's latency is.

    I would change your example to look like this:

    GET /posts/

    {
           "total": 10,
           "limit": 2,
           "offset" 3,
           "results": [

              {
                  "id": 1,
                  "title": "Rails is omakase",
                  "comments": [
                      {
                          "id": 1,
                          "body": "But is it _lightweight_ omakase?"
                      },
                      {
                          "id": 2,
                          "body": "I for one welcome our new omakase
    overlords"
                      },
                      {
                          "id": 3,
                          "body": "Put me on the fast track to a
    delicious dinner"
                      }
                  ]
              },

              {
                  "id": 2,
                  "title": "Rails is omakase",
                  "comments": [

                      {
                          "id": 5,
                          "body": "But is it _lightweight_ omakase?"
                      },
                      {
                          "id": 6,
                          "body": "I for one welcome our new omakase
    overlords"
                      },
                      {
                          "id": 10,

                          "body": "Put me on the fast track to a
    delicious dinner"
                      }
                  ]
              }
          ]
    }

    And the individual GET to /post/:id would return one of those
    hashes in the results array.  To me, a comment is a sub-resource
    of a post (I'm making the assumption that a comment cannot exist
    without a post).

    For what it's worth, I've used Ember.js at a past company and I
    am not a fan.  It seemed convoluted, poorly documented, and slow
    (though to be fair, it wasn't yet 1.0 when we were using it).

    AngularJS, on the other hand, is straightforward, well
    documented, and fast.

    Cheers,
    Walden



    ----- Original Message -----
    From: "Joseph Magen" <jmagen@redhat.com <mailto:jmagen@redhat.com>>
    To: "foreman-dev" <foreman-dev@googlegroups.com
    <mailto:foreman-dev@googlegroups.com>>__,
    katello-devel@redhat.com <mailto:katello-devel@redhat.com>
    Sent: Wednesday, July 10, 2013 2:41:12 AM
    Subject: [katello-devel] JSON API v2 conventions discussion

    I've been reading how different API clients prefer different
    JSON responses and that there is no standard "convention over
    configuration".  For example, Ember.js prefers the _ids as an
    array in the root node, whereas other JS clients prefers to
    transverse the id's in the child nodes. (see ex. below)

    My questions:
    1) Is there a particular API JSON convention that the Foreman
    Hammer CLI prefers?
    2) Is Katello consuming the Foreman API or plan to in the future?
    3) Is Foreman consuming the Katello API or plan to in the future?
    4) Are the Katello API and Foreman API v1 conventions similar or
    different?
    5) What other JSON clients / frameworks do we know about that
    are big consumers of Foreman API

    Here is an example of side-loaded relationships from the
    Ember.js documetation.

    http://emberjs.com/guides/__models/the-rest-adapter/#toc___sideloaded-relationships
    <http://emberjs.com/guides/models/the-rest-adapter/#toc_sideloaded-relationships>

    ---
    To reduce the number of HTTP requests necessary, you can
    sideload additional records in your JSON response. Sideloaded
    records live outside the JSON root, and are represented as an
    array of hashes:

    {
        "post": {
          "id": 1,
          "title": "Rails is omakase",
          "comment_ids": [1, 2, 3]
        },

        "comments": [{
          "id": 1,
          "body": "But is it _lightweight_ omakase?"
        },
        {
          "id": 2,
          "body": "I for one welcome our new omakase overlords"
        },
        {
          "id": 3,
          "body": "Put me on the fast track to a delicious dinner"
        }]
    }
    ---

    Regards,

    Joseph

    _________________________________________________
    katello-devel mailing list
    katello-devel@redhat.com <mailto:katello-devel@redhat.com>
    https://www.redhat.com/__mailman/listinfo/katello-devel
    <https://www.redhat.com/mailman/listinfo/katello-devel>

    _________________________________________________
    katello-devel mailing list
    katello-devel@redhat.com <mailto:katello-devel@redhat.com>
    https://www.redhat.com/__mailman/listinfo/katello-devel
    <https://www.redhat.com/mailman/listinfo/katello-devel>


--
You received this message because you are subscribed to the Google
Groups "foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to foreman-dev+unsubscribe@__googlegroups.com
<mailto:foreman-dev%2Bunsubscribe@googlegroups.com>.
For more options, visit https://groups.google.com/__groups/opt_out
<https://groups.google.com/groups/opt_out>.


You received this message because you are subscribed to the Google
Groups “foreman-dev” group.
To unsubscribe from this group and stop receiving emails from it, send
an email to foreman-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.