Loomio

Request for comments: API specification draft

DS
Dennis Schubert Public Seen by 534

So, since we now have a nice API authentication implemented I think we should ship 0.6.0.0 with an API if we manage to implement it in time. Initial work was already done in #6636 but after taking a look with it, I felt like we really should think about a proper structure for our API, especially since our backend models are rather... complex and simply exposing anything to our API does not feel like the right thing to do.

The initial work by @theworldbright was based on jsonapi, but after a small chat over IRC, we both agreed that following jsonapi creates a lot of unnecessary overhead. So I went ahead and wrote an API proposal (actually, I wrote a whole documentation so we would be ready to go...) and I'd like to have some feedback. Most of the routes are simple RESTy JSON routes. Pagination is done via Link headers which also is a somewhat "usual" approach that I have seen in various places, for example in GitHubs API.

There we go: https://diaspora.github.io/api-documentation/

Feel free to ask any questions and make suggestions. If you find a spelling or grammar error, please submit a PR and keep that out of Loomio since that would create a lot of noise. ;) If no one has objections, I'd move the repository over to the org rather sooner than later and add links to the wiki, so everyone interested in API work has an easy time finding that documentation.

SVB

Steffen van Bergerem Sat 20 Feb 2016

I already did a few reviews in the last couple of days and did a final review a few minutes ago. The proposal looks good to me.

AL

Armando Lüscher Sat 20 Feb 2016

For the Notifications:
All notification types are set to past tense except for "comment_on_post".
I'd suggest and encourage to change this to "commented_on_post" to follow the same structure.

Other than that I've made a few PRs and am seriously looking forward to the API becoming reality!
Awesome work, thanks!

C

Creak Sat 20 Feb 2016

That seems pretty awesome.

I don't know much about the architecture of D*, but if there is no such API as of today, does it mean that D* makes direct calls to the backend to fetch the data to display?

C

Creak Sat 20 Feb 2016

I'm not a lot familiar with REST APIs, so the next question might be stupid.

What is the meaning of ":" in the URL?
For instance, to get the information about an aspect, it's written like that:

GET /api/v1/aspects/:aspect_id

But why not using "?" as a separator between the request and the arguments? Like something like that:

GET /api/v1/aspects/?id=aspect_id

That allows to use GET method for most, if not all, of the requests.

SVB

Steffen van Bergerem Sat 20 Feb 2016

If the aspect id is 4 then the route would be

GET /api/v1/aspects/4

This is important for routes like the one to receive comments of a post. If the post guid is 23 then you can get the comments with

GET /api/v1/posts/23/comments

The colons just tell you that this is a parameter that needs to be set to the correct value.

C

Creak Sat 20 Feb 2016

Oh ok!

I thought it meant that we should do that:

GET /api/v1/aspects/:4

So that brings me to my next point: would be nice to add one or two examples after the Request and Response sections ;)

SVB

Steffen van Bergerem Sat 20 Feb 2016

would be nice to add one or two examples after the Request and Response sections

I think those who read the specs because they would like to write software that uses the API will be able to understand the current state of the specs. Especially because they will have to work on the OpenID connect authentication first.

MV

Manuel Vögele Sun 21 Feb 2016

Seems like the the feature to reorder aspects is missing. But aside from that it looks good to me.

DS

Dennis Schubert Mon 22 Feb 2016

@manuevogele yeah, why not. I added the aspect order id. Thanks!

K

Kitsune Thu 25 Feb 2016

I've skimmed over the spec. For me as a layman, it makes a very good and clean impression. One central question: what about error handling? Will there be a combination of HTTP error code and a standard JSON object with qualified error information? (I asked myself what happens, when the client is trying to create a new conversation and the client GUID is missing in the recipients list? A HTTP status code like 403 seems to be too little in this case.)

K

Kitsune Thu 25 Feb 2016

Shame on me! Didn't read the hint in the overview ... But it's quite interesting for me :)

DF

Deus Figendi Thu 3 Mar 2016

Looks verry well…

GET /api/v1/photos/:photo_guid

Isn't there more information but dimensions and sizes? Maybe the datetime of upload? Or corresponding postings?


Posts → Publish a post → Poll

says "see above". Is it really nessesary to tell points like participation_count, vote_count or already_participated?


What's the difference of GET /api/v1/streams/tags and GET /api/v1/search/posts ?


I am missing "add user to aspect(s)" or "share with user" or the like.


In the end: Looks like a lot of work, hours and hours of writing, thanks for that.

K

Kitsune Fri 4 Mar 2016

General
* diaspora_id: I don't like product specific / platform specific names in a functional oriented interface. I would prefer a more neutral alternative like "handle", "federation_id", or "identifier". (As I understand, the diaspora_id is also used to address Friendica and Red Matrix users?)

Contacts
* Add a user: GUID is transfered by resource URL. An alternative way could be a JSON object. This would be a more consequent resp. "stringent" (but maybe a "non-comfortable") way in comparison of other POST methods in the spec. Example: POST /api/v1/aspects/:aspect_id/contacts/ { "guid": "0a992a10b9db0133e40e406c8f31e210" }

Posts
* Advanced Post Contents: maybe, this should be separated in request and response views. For instance, the polls object contains "guid", "participation_count", and "already_participated". This looks like a set of response attributes, but I assume that polls can also be used in requests for new posts?
* Mentions: Is this for response objects only? If both ways: Why is it the job of the client to extract the mentions as separate user objects? (And how does the client get the needed user data?)

Streams
* Get the main stream -> Response -> post_type: this looks like an enum value. Which values are possible and what is their meaning?

Users
* Get information about a single user -> „block“: Alternative name: "blocked" ("block" is - from my point of view - an imperative mood, but the attribute is not used in a command-like context?).
* Update the currently authenticated users profile -> Request/Response -> birthday: Which format is expected? Why not ISO (YYYY-MM-DD), as it is used in the database?
* Update the currently authenticated users profile -> Request -> name: I guess that's the display name? But isn't it neccessary to transmit first_name and last_name separated for the update process (according to the database structure)?
* Update the currently authenticated users profile -> Response -> name: Is this the "combined" display name which is created via first_name + blank + last_name? (Should be mentioned in the explanation to clarify the interface's behavior.)

Users vs. User
I don't have a good feeling for the resources under /api/v1/user and /api/v1/users. First, I thought it's a single resource because I didn't notice the singular-plural distinction - it confused me for a while. For me, a user is a technical account on a specific pod which is used primarily for session handling (authentication, authorization, etc.). This account can be furthermore associated with a profile, which is the non-technical view on a person or principal. What I'm trying to say: the resource under /api/v1/users should be more a /api/v1/people or /api/v1/profiles (like the database structure, where "people" and "profiles" are used). BTW: in the mentions object (Posts section) "mentioned_people" is used instead of "mentioned_users".

G

goob Sat 5 Mar 2016

diaspora_id: I don’t like product specific / platform specific names in a functional oriented interface.

Perhaps user-id?

DF

Deus Figendi Thu 24 Mar 2016

Oh btw. I don't like that photos are called photos all over diaspora (in the database and the json-responses even in the UI). I'd say "images" would be the best term for these, because not every image uploaded is photo, half of the pictures I upload ain't photos but "graphics" (or "graphs" ;D).

So I suggest to start in the api calling this stuff "image" or "images" instead of "photos". Maybe it's a bad idea to make this less continuous but I don't like at all this kinda stuff is called photos.

M

Miko Sun 27 Mar 2016

thx

CS

Comrade Senya Mon 28 Mar 2016

How will diaspora api version be exposed with Nodeinfo? In the software section?

DF

Deus Figendi Thu 28 Apr 2016

Today I thought about a usecase one would need to access /public/ (all public posts on a pod). Maybe huge or weak pods would like to deactivate that. Or maybe podmins general want to restrict the frequence of requests.

And I couldn't find any error-handling. Many errors might occur like no data for a request or invalid parameters or to many requests per time…

R

Ruso Wed 28 Sep 2016

This can be autogenerated like Propel ORM?

DS

Dennis Schubert Sun 6 Nov 2016

All notification types are set to past tense except for "comment_on_post".
I'd suggest and encourage to change this to "commented_on_post" to follow the same structure.

Thanks, fixed.

Maybe the datetime of upload? Or corresponding postings?

Both added.

What's the difference of GET /api/v1/streams/tags and GET /api/v1/search/posts?

One shows the tags you're following, the other allows you to search for a tag...

I am missing "add user to aspect(s)" or "share with user" or the like.

https://diaspora.github.io/api-documentation/routes/contacts.html

diaspora_id: I don't like product specific / platform specific names in a functional oriented interface.

This is the way we called the field internally. Names like ID are ambiguous, since that could be the numerical ID or the GUID as well.

Add a user: GUID is transfered by resource URL. An alternative way could be a JSON object.

I don't really like that. First, your suggestion should be a PATCH, not a POST. That may work for adding. But how would you do deletions?

Advanced Post Contents: maybe, this should be separated in request and response views.

Maybe. I'd like to avoid duplicate content. Will add that if we run into confusions. :)

Mentions: Is this for response objects only? If both ways: Why is it the job of the client to extract the mentions as separate user objects? (And how does the client get the needed user data?)

It's response only, yes. I don't understand your second question.

Get the main stream -> Response -> post_type: this looks like an enum value. Which values are possible and what is their meaning?

"The post_type field in a response could either be StatusMessage or Reshare."

Get information about a single user -> „block“: Alternative name: "blocked"

Good point. Fixed.

Update the currently authenticated users profile -> Request/Response -> birthday: Which format is expected?

Added ISO 8601, thanks.

Update the currently authenticated users profile -> Request -> name: I guess that's the display name? But isn't it neccessary to transmit first_name and last_name separated for the update process

Well. Yeah. Fixed.

Users vs. User

Good points. Singular/plural routes are nothing unusual. I don't want to split between people and profiles since users and developers should not care, but I'll keep your points in mind if we ever run into trouble. Thanks!

And I couldn't find any error-handling.

That's the only ToDo point. ;)

This can be autogenerated

Nah. Our database structure looks very different from what we expose. The database schema is way too complicated for an API. ;)

DS

Dennis Schubert Sun 6 Nov 2016

Actually, I've reverted the first name and last name split. See https://github.com/diaspora/diaspora/issues/3648