Diaspora API Interactions Part 2: The First "Real" Interaction

I was so excited when I finally got a real pod interacting with the API that I knew I’d have to get it written down before I could get to sleep. However before dropping right to the interactions itself I decided to take some time describing how a piece of software would be allowed to do anything with a server. In Part1 I laid all of those details out to get across some very important points:

  • We are using a standard (OpenID/OAuth2) protocol for doing this
  • Users have to give explicit permissions to an application, including being told what it is and is not asking to do
  • There are security measures once an application is granted permissions as well.

This article essentially details the very first communications and gives people a feel for what the Diaspora API specification looks like in practice not just in theory.

Where we left off from Part1 is that we have a valid access token. For these examples I’m going to use a shortened version for the sake of brevity which will be: d003c. The responses below will be the actual responses from the server since none of that is “secret” data like the access tokens, client secrets, etc. With this access token, and this particular application asked to do literally everything the API allowed, we want to make the most basic of calls: we want to get the user profile information for the user whom is associated with this token.

The REST call looks like this: https://hanksdiasporadevtestpod.com/api/v1/user?access_token=d003c It return the profile information in JSON format:

{
  "first_name": null,
  "last_name": null,
  "diaspora_id": "hankdevtest@hanksdiasporadevtestpod.com",
  "avatar": {
    "small": "/assets/user/default-2c878d1cd0171726fc490add065f342be5a959729df46a89807a4c18a8fc8d14.png",
    "medium": "/assets/user/default-2c878d1cd0171726fc490add065f342be5a959729df46a89807a4c18a8fc8d14.png",
    "large": "/assets/user/default-2c878d1cd0171726fc490add065f342be5a959729df46a89807a4c18a8fc8d14.png"
  },
  "tags": [],
  "birthday": null,
  "gender": null,
  "location": "",
  "bio": "",
  "searchable": true,
  "show_profile_info": false,
  "nsfw": false,
  "guid": "89fe4e60ed360136cdc8463a100c9a4c"
}

As you can see I haven’t set much in my test profile at this point, not even my name. However there is some valuable information there: specifically the diaspora_id and the guid. The Diaspora ID is useful for things like mentioning people in posts or searching for them. The GUID is even more important. This will be used in certain REST calls to identify the user we want information for or to interact with. Before we use that though let’s make a post.

The Post API endpoint has a REST POST method for doing just that. The API documentation shows the wide variety of fields that can be passed in but we just want to create the simplest of messages: a public text only post. The call and the JSON data passed in is very straight forward (the JSON data is the actual call but the access token is the fake one here):

https://hanksdiasporadevtestpod.com/api/v1/posts?access_token=d003c
{
    "body": "This is the first post made through the API to a production pod (albeit the dev-test pod) ever! Yay progress on getting the API #diaspora #diaspora-dev #fediverse",
    "public": true
}

Assuming the post is successful then the Diaspora API returns back all of the data about the post:

{
  "guid": "f7793300ed3b0136cdc8463a100c9a4c",
  "body": "This is the first post made through the API to a production pod (albeit the dev-test pod) ever! Yay progress on getting the API #diaspora #diaspora-dev #fediverse",
  "title": "This is the first post made through the API to a production pod (al...",
  "post_type": "StatusMessage",
  "public": true,
  "created_at": "2018-12-29T02:04:15.321Z",
  "nsfw": false,
  "author": {
    "guid": "89fe4e60ed360136cdc8463a100c9a4c",
    "diaspora_id": "hankdevtest@hanksdiasporadevtestpod.com",
    "name": "hankdevtest@hanksdiasporadevtestpod.com",
    "avatar": "/assets/user/default-2c878d1cd0171726fc490add065f342be5a959729df46a89807a4c18a8fc8d14.png"
  },
  "provider_display_name": null,
  "interaction_counters": {
    "comments": 0,
    "likes": 0,
    "reshares": 0
  },
  "location": {
    "address": null,
    "lat": null,
    "lng": null
  },
  "poll": null,
  "mentioned_people": [],
  "photos": [],
  "root": null
}

As you can see it has lots of valuable information about the post and the post author. This would allow an application to do something like render the post text and grab the author’s avatar icon from the server and render that along side it, for example. The part of the JSON where the author data is written will appear in many places throughout the API with the exact same format. It can be useful for getting additional information, say by getting all the posts for a user that commented on one of your posts. How would an application go about doing that? All it would need to do is use the User API’s posts method to ask for that information. So let’s do that by taking the author GUID (which happens to be the same as the logged in user in this case) and get a list of posts:

https://hanksdiasporadevtestpod.com/api/v1/users/89fe4e60ed360136cdc8463a100c9a4c/posts?access_token=d003c

In this case we will get back the original “welcome” post created manually when the account was created and our new post in reverse chronological order (just like on the stream in the UI):

{
  "links": {
    "previous": "https://hanksdiasporadevtestpod.com/api/v1/users/89fe4e60ed360136cdc8463a100c9a4c/posts?access_token=d003c\\u0026after=2018-12-29T02:04:15.322Z",
    "next": "https://hanksdiasporadevtestpod.com/api/v1/users/89fe4e60ed360136cdc8463a100c9a4c/posts?access_token=d003c\\u0026before=2018-12-29T01:26:35.646Z"
  },
  "data": [
    {
      "guid": "f7793300ed3b0136cdc8463a100c9a4c",
      "body": "This is the first post made through the API to a production pod (albeit the dev-test pod) ever! Yay progress on getting the API #diaspora #diaspora-dev #fediverse",
      "title": "This is the first post made through the API to a production pod (al...",
      "post_type": "StatusMessage",
      "public": true,
      "created_at": "2018-12-29T02:04:15.321Z",
      "nsfw": false,
      "author": {
        "guid": "89fe4e60ed360136cdc8463a100c9a4c",
        "diaspora_id": "hankdevtest@hanksdiasporadevtestpod.com",
        "name": "hankdevtest@hanksdiasporadevtestpod.com",
        "avatar": "/assets/user/default-2c878d1cd0171726fc490add065f342be5a959729df46a89807a4c18a8fc8d14.png"
      },
      "provider_display_name": null,
      "interaction_counters": {
        "comments": 0,
        "likes": 0,
        "reshares": 0
      },
      "location": {
        "address": null,
        "lat": null,
        "lng": null
      },
      "poll": null,
      "mentioned_people": [],
      "photos": [],
      "root": null
    },
    {
      "guid": "b4898700ed360136cdc6463a100c9a4c",
      "body": "Hey everyone, I’m #newhere. I’m interested in #diaspora, #diaspora-dev, #fediverse, #linux, and #ruby. ",
      "title": "Hey everyone, I’m #newhere. I’m interested in #diaspora, #diaspora-...",
      "post_type": "StatusMessage",
      "public": true,
      "created_at": "2018-12-29T01:26:35.646Z",
      "nsfw": false,
      "author": {
        "guid": "89fe4e60ed360136cdc8463a100c9a4c",
        "diaspora_id": "hankdevtest@hanksdiasporadevtestpod.com",
        "name": "hankdevtest@hanksdiasporadevtestpod.com",
        "avatar": "/assets/user/default-2c878d1cd0171726fc490add065f342be5a959729df46a89807a4c18a8fc8d14.png"
      },
      "provider_display_name": null,
      "interaction_counters": {
        "comments": 0,
        "likes": 0,
        "reshares": 0
      },
      "location": {
        "address": null,
        "lat": null,
        "lng": null
      },
      "poll": null,
      "mentioned_people": [],
      "photos": [],
      "root": null
    }
  ]
}

Obviously this looks a lot like the return data we got from the original post response but now for two posts instead of one. The API documentation will be useful for studying the details of the format itself. However beyond the fact we have two posts notice that we have them in a data field. There is also a links field at top as well. This is part of the API’s paging system, as it is implemented at the time of this writing at least. Almost all endpoints that return multiple pieces of data return them as paged results. This is critical for most parts of Diaspora. A developer wants to be able to see all of a user’s posts but they don’t want to get thousands of posts back all at once. Using the links the program is able to navigate back and forth through a data set getting only a reasonable number of results in each “page” of data.

This was a brief tour of the interactions with the Diaspora API, specifically the very first calls made to a production pod. As this is still in development formats may change, responses may be slightly different, etc. in the final implementation. Please refer to the Diaspora API when you are developing for ground truth data of the final format et cetera. I’ll try to update this as those changes but there is a chance I’ll end up missing something. With that caveat, I hope you enjoyed this brief tour. Keep an eye out for some additional updates soon on the first real world “dog fooding” of the API system and the dev-test pod.