Introducing PONAPI a Perl implementation of {json:api}


#1

Hi, we’d like to introduce a new server (soon there will be a client) distribution that supports the spec (v1.0) which is fully written in Perl.

The distribution is available on CPAN:

And has a GitHub repo:

The service comes with an out-of-the-box mockup SQLite DB which we built from the examples on the site, used for testing and proof of concept.

Our employer, Booking.com supported the development and release of PONAPI as open-source project.

It’s still in trial-release mode until we clear some known issues, but would appreciate all feedback we can get to improve it.

blog posts and tutorials to follow with the coming full release.

:wink:


#2

Oh nice! :smiley:

You should send a PR to the website to get it listed.


#3

I just did, thank you.


#4

@mickey Glad to see Perl implementation.

You have bad example in Moreso, fields can be combined with include. The following response is invalid as according to specification a compound document should be fully linked.

data => [
    { type => "articles", id => 2, },
    { type => "articles", id => 3, },
],
include => [
    {
        type => 'people', id => 44,
        attributes => { name => "Foo" },
    },
    {
        type => 'people', id => 46,
        attributes => { name => "Bar" },
    }
]

you have the following request:

type    => 'articles',
include => [qw/ authors /],
fields  => {
    articles => [], # no attributes or relationships
    people   => [qw/ name /],
},

response shouldn’t have any objects included at all as there is no filter[articles][]=authors argument.

To get more expected response request should have:

type    => 'articles',
include => [qw/ authors /],
fields  => {
    articles => ['authors'],
    people   => [qw/ name /],
},

And response would be:

data => [
    { type => "articles", id => 2, relationships => { authors => [{type => 'people', id => 44}] } },
    { type => "articles", id => 3, relationships => { authors => [{type => 'people', id => 46}] } },
],
include => [
    {
        type => 'people', id => 44,
        attributes => { name => "Foo" },
    },
    {
        type => 'people', id => 46,
        attributes => { name => "Bar" },
    }
]

See second note in the following section http://jsonapi.org/format/#fetching-includes


#5

@ruz thanks.
we’ll fix that.


#6

I don’t speak perl, so I don’t understand the above requests exactly, but I just want to point out for reference that the “full linkage” @ruz mentioned does have one exception:

The only exception to the full linkage requirement is when relationship fields that would otherwise contain linkage data are excluded via sparse fieldsets.

So, if your response above is missing the author linkage because the author field has been excluded with fields[people], that is ok


#7

I think the filter reference is wrong there, the key is fields.

let me just try to explain what we tried to do here:

the above example the fields query parameters are equivalent to: …fields[articles]=&fields[people]=name…

we chose to see the empty value as a valid empty CSV list to indicate ‘no attributes/relationships for this type’ (if that’s a wrong assumption we can change that, that came out of the way we implemented it and we just stuck to it).

the idea in this test case was to exclude all from articles, but include name for people so it was included based on the actual relationship between them regardless of whether this relationship is shown.

thanks everyone, we appreciate the feedback.


#8

@mickey looks like I’m wrong.

@ethanresnick Oh. This was hard to find and I totally missed it while was reading the spec. May be it should standout a bit in the doc. Also, second block of notes I mentioned earlier may mention this too.


#9

Agreed. I’ll work up a PR.


#10

Ok @ruz, I made the pr. Take a look and let me know (on Github) if you think it clears things up enough or if there are other changes you’d like.


#11

Better, I would bold “only exception” or “exception”, but this new version is already better. Thank you.


#12

No problem! Thank you for reporting the part that was confusing :smile:

I don’t really feel comfortable bolding “only exception”, since the only other text that’s bold is the normative keywords (MUST, SHOULD, etc.). But if you have any other ideas, feel free to leave them in the PRs comments!


#13

I expected such reply as saw bold usage too.


#14

Howdy all, I’m another dev working on PONAPI. Thanks for the feedback! I got the impression @ruz was actually discussing two bugs at once, but maybe I just got confused – was wondering if I could get some clarification : )

  • fields and full-linkage in include.
    That looks covered by the PR, but to be super clear, it means that in GET /articles?include=authors&fields[people]=name the included authors in include will not have any relationships and the only attribute shown will be name:

    “included”:[
    {“type”:“people”,“id”:1,“attributes”:{“name”:“foo”}}
    ]

  • fields excluding a relationship in the main resource, but that relationship is requested in include.
    For example, base request:

    GET /articles/1
    "data": {
    “type”: “articles”,
    “id”: 1,
    “attributes”: {
    “title”: “great title!”
    },
    “relationships”: {
    “author”: {
    “data”: {
    “type”: “people”,
    “id”: 22
    }
    }
    }
    }

Same request, but now we only want the title; this excludes all relationships:

GET /articles/1?fields[articles]=title
"data": {
  "type": "articles",
  "id": 1,
  "attributes": {
    "title": "great title!"
  },
}

Finally, same as above, but with include=author; should included here be empty, or have the author, which is not in data due to fields?

GET /articles/1?fields[articles]=title&include=author
"data": {
  "type": "articles",
  "id": 1,
  "attributes": {
    "title": "great title!"
  },
},
"included": [
    ???
]

Cheers!


#15

included should have the author even though the linkage to the author won’t occur in data


#16

I don’t speak Perl either, but from skimming over the API, it appears that the library can only work with URIs of the form host:port/type/id. If so, that would make it a rather limited JSON API library, and not at all “able to communicate with any API-compliant service.” Perhaps the methods can be made to accept an explicit url parameter (as obtained from the links, for instance) as an alternative to type+id?


#17

assuming you refer to the client (PONAPI::Client) - I agree we can accept a template to generate the URI.
thanks for the input, feel free to open issues on our project’s GH page: https://github.com/mickeyn/PONAPI/issues