Skip to content

Tutorial: Create new services using ASI

sktoiva edited this page Sep 14, 2010 · 9 revisions

What is Aalto Social Interface?

OtaSizzle’s Aalto Social Interface (ASI) is a web service that provides a centralized social network and a platform for external services. ASI has a public REST API which can be accessed over the web from various technologies and programming languages. ASI stores information about people (profiles, avatars, friendships), groups, location and handles some common functionalities like logging in, sessions and sending mail (soon) to users.

Although ASI interface is not strictly RESTful, it follows the general logic of using the 4 following HTTP methods to make all calls.

GET – to get a resource
POST – to make a new resource
PUT – to update a resource
DELETE – to delete a resource

Developing a new service

How to access Aalto Social Interface development server?

To access ASI you need an application account and password. You can ask those by contacting us (email to cos at cs.hut.fi). Include in the email a short description of your idea and the name of your application. In the beginning, the application account will work only on ASI development server (cos.alpha.sizl.org), but when you reach a stable state in with your application, contact us again to get access to the production ASI (cos.sizl.org).

All the real OtaSizzle user accounts are on the production ASI. The development ASI contains only test data, although some users may have similar username in both servers.

How to test connection to ASI

To test the REST interface, you can use the interactive tester

It lets you select which type of HTTP request you want to send (GET, POST, PUT, DELETE), to which address (see the paths in ASI API), and which parameters you want to send with the request. The parameters are entered like this: “firstVariable=value&secondVariable=value2”. When you press “Execute” you will see the response from ASI below the form.

The response contains two parts. The HTTP status code and the body. The code tells the overall result of the request and the body may contain more specific information.

You can try logging in with your application account.

How to log in to ASI and manage sessions

NOTE: There will be a single-sign-on system coming for ASI login, that is planned to eventually replace this simple REST+cookie login system. However, this is currently the only way for login and we are not planning to remove support for this type of login any time soon.

Sessions

ASI has 2 types of sessions:

  • “application only” session aka. app_only session
  • a session bound to a specific user account aka. “user session”

A user session always contains information also about the application. So, to start an app only session, you need only application name and application password. To start a user session you need also username and user’s password besides the application credentials.

Logging in and out

Logging in is done simply by “posting a session”. That means sending a POST HTTP request to URL ASI_SERVER/session. If you are using the development ASI, the ASI_SERVER is http://cos.alpha.sizl.org (session URL is then: http://cos.alpha.sizl.org/session). If you are using the interactive tester, the session URL is just /session.

The parameters needed to open a session are documented in: http://cos.alpha.sizl.org/doc/session

To test your application account, do the following in the interactive tester:

POST /session

(with params)

 session[app_name]=your_app_name&session[app_password]=your_app_password

You should get response looking like:

 Code: 201
Body: {"app_id":"your_app_id","user_id":null}

After this, you can check if you are logged in by using GET to the same URL, for example:

 GET /session

(“with params” should be left empty, actually the params field won’t be read at all for GET requests. If you want to put some params in a get request, put them in the url part, for example: http://cos.alpha.sizl.org/people?search=antti)

You should get a response like:

Code: 200
Body: {"app_id":"your_app_id","user_id":null}

Note that the user_id associated to the session is null, which means this is an app_only session.

Logging out works with the same logic:

 DELETE /session

(“with params” can be empty again, no parameters are needed.)

 Code: 200
Body: {}

Session cookies

ASI keeps track of different sessions with cookies (even though it is not really RESTful). Depending on the platform from which you are making the HTTP calls, the cookies may be managed automatically. If they are not, you have to store and send them manually.

In browsers, cookie management is nearly always automatic, so for example in interactive tester, you don’t need to worry about cookies (as long as they are turned on in your browser settings.)

If you develop a Rails server application that wants to open a session to ASI, you need to manage cookies manually. The Ruby HTTP module used by Rails by default doesn’t seem to do it automatically. (There are others HTTP modules available for Ruby that may be better in cookie handling, but that topic is not covered here.) Below are simple instructions to store and send cookies in Rails.

Manual cookie management

The session cookie is a long string value that you get with the response each time when you log in. You have to store the string and send it with your further requests that you want to be associated with the same session in ASI. If your application has multiple cookies stored at the same time, it can have as many open sessions to ASI simultaneously. Since on session can be bound to only one user, that is usually the case when your services has multiple simultaneous users.

A session cookie is invalidated when you send the DELETE /session request with the cookie (= Logging out) or by the server after an idle time long enough.

Getting the cookie

The cookie string can be found on the response to the POST /session request. It is in the header field “set-cookie”. An ActiveResource example:

  params = {}
params[:username] = @username 
params[:password] = @password
params.update({:app_name => @@app_name, :app_password => @@app_password})
response = connection.post("/session", params.to_json)
cookie = response.get_fields("set-cookie").to_s
Sending the cookie

When you want to do a request that belongs to a session already opened, you have to add the cookie to the request’s headers. An ActiveResource example:

 response = connection.get("/session", {"Cookie" => cookie})

or

 response = connection.put("/people/#{id}/@self",{:person => params}.to_json, {"Cookie" => cookie} )

The parameters for connection.get are (path, headers) and for others (path, parameters, headers)

Using the REST API

What is REST?

Simply put, it means accessing resources over HTTP without additional message layers or wrappers. It should be stateless, so using cookies makes ASI to fall out from the category of strictly RESTful applications, but anyway, the principles are otherwise similar, so it makes sense to call the ASI API a REST API. You can read more about REST for example from the [http://en.wikipedia.org/wiki/Representational_State_Transfer Wikipedia].

Examples

To access a resource, you post a HTTP request (GET, POST, PUT or DELETE) to a path on the ASI server with certain parameters. The often used formats for parameters and responses are JSON and XML. ASI currently supports only JSON.

Here are some examples with explanations. To see all the possible calls, see ASI API documentation

Fetch a profile of single user with id bU8aHSBEKr3AhYaaWPEYjL

GET http://cos.alpha.sizl.org/people/bU8aHSBEKr3AhYaaWPEYjL/@self

(Note: The format of the URL originates from OpenSocial RESTful Protocol Specification . At the moment, ASI is only partly compliant with the specification.)

If the user is found, code “200 OK” and a response body similar to following (line breaks added for readability) is returned:

{
  "status": 
  { 
    "changed": "2009-05-14T14:06:40Z", 
    "message": "fooling around" 
  },
  "name": 
  { 
    "family_name":" Virolainen", 
    "unstructured": "Antti Virolainen", 
    "given_name":"Antti" 
  },
  "connection": "you",
  "birthdate": "1983-01-01",
  "role": null,
  "phone_number": "050-5555555",
  "username":"gnomet", 
  "gender": 
  { 
    "displayvalue": "MALE", 
    "key": "MALE" 
  },
  "id":"bU8aHSBEKr3AhYaaWPEYjL",
  "avatar": 
  { 
    "status": "set", 
    "link": 
    { 
      "href": "\/people\/bU8aHSBEKr3AhYaaWPEYjL\/@avatar", 
      "rel":"self" 
    } 
  },
  "msn_nick": null,
  "irc_nick": null,
  "address": 
  { 
    "unstructured": "JMT, 02150 ", 
    "street_address": "JMT", 
    "postal_code": "02150", 
    "locality": "" 
  },
  "location": 
  { 
    "latitude": 60.189068625,
    "updated_at": "2009-04-14T11:20:41Z", 
    "longitude": 24.806418875, 
    "label": null, 
    "accuracy": null 
  },
  "email": "[email protected]"
}

Note that some JSON fields may be missing for some requests. The reason can be that the user has not set that value in his profile, or it is not shown for the asker. For example the email address is shown only to the person himself.

Updating the status message of a user

 PUT http://cos.alpha.sizl.org/people/bU8aHSBEKr3AhYaaWPEYjL/@self

with parameters:

 person[status_message]=testing...

would give a response (with code 200):

{
  "status":{"changed":"2009-05-21T16:55:32Z","message":"testing..."},
  "name":{"family_name":"Virolainen","unstructured":"Antti Virolainen","given_name":"Antti"},
  "birthdate":"1983-01-01",
  "phone_number":"050-5555555",
  "username":"gnomet",
  "gender":{"displayvalue":"MALE","key":"MALE"},
  "id":"bU8aHSBEKr3AhYaaWPEYjL",
  "avatar":{"status":"set","link":{"href":"\/people\/bU8aHSBEKr3AhYaaWPEYjL\/@avatar","rel":"self"}},
  "msn_nick":null,
  "irc_nick":null,
  "address":{"unstructured":"JMT, 02150 ","street_address":"JMT","postal_code":"02150","locality":""}
}

So, it generally returns the basic profile information, but more importantly the HTTP code 200 which tells that the request is completed successfully.

As a shorthand notation for the id of the logged in user you can also use @me instead of user_id in requests:

PUT http://cos.alpha.sizl.org/people/bU8aHSBEKr3AhYaaWPEYjL/@self 

equals

PUT http://cos.alpha.sizl.org/people/@me/@self

JSON

To see more detailed explanation of JSON format, see: json.org. Usually, it is not necessary to parse the JSON manually as many programming languages have support built in or available as a plugin.