#425: Noosfero Public API — a web-service API

Type: FeatureItem Feature: API, Infrastructure, Plugins, SocialNetwork Tags:  
ScheduledFor: N/A Assigned to: AurelioAHeckert Sites:  
Priority: 0 Status: Working  

The Noosfero needs a public API like any other web 2.0 application.

Noosfero is social. Social means public interactive, and that means unexpected and fast personal or independent connected usage.

This page will be first used to plan the public webservice API structure.

Premisses

The Noosfero project wants the federated social web, and that defines some public APIs, So the plan must consider all this needs first (see the list). There are other social applications with their own APIs (see that list). It will benefit the public better if Noosfero clones these standards, like StatusNet did based on Twitter.

The API may be freely used by classical XML based applications or by any web-page via JSON. Both formats are important for all methods. To allow any page (on any domain) to load data from the noosfero API, the JSON response must be "enveloped" by a callback function, like used by Twitter and SatusNet.

Any response must contain an error element in the root element to allow a fast and inteligent error handling.

The API may start simply to interact services, but we must to consider the possibility to use all noosfero features through the API, and allowing, in the future, a JS web UI without redirects.

Related Feature Requests

This topic is about web-services API. To talk specifically about Federation, see: Federation related AIs and the ActionItem2815.

Social Service APIs

Structure

The api directory must be on the web root and the context profile inside a major version directory. The major version directory will preserve te compatibility with clients created for some old API version. A last word may link for the newer version of the api method. The method comes inside the context profile directory as the last path element, and its parameters come after the ? as a commom GET paramater allowing to name each parameter. That also allows to evolve the parametrization with reduced risk of breaking compatibility. The context profile directory is the profile name (community, person, or enterprise) and is in this profile where the method will act. A env context is also useful for profile independent methods, like search. The methods return type is set as a method extension.

The API methods must be implemented by plugins, allowing independent steps to complete this and simple local extensions. To do this a base core router will send requests to an API infra controller witch will run the proper method.

The router will have this structure:
http://test.noosfero.net/api/{version}/{module}[/{method}[/{id}]].{format}?{params}

The parameters means:
  • {version}: API version. Signature and JSON/XML structure guarantee.
  • {module}: Maybe a profile reference by its identifier, or another implemented API module.
    The planed modules are:
    • person: used when {module} is a person identifier, like http://test.noosfero.net/api/1/darth-vader/friends.json
    • community: used when {module} is a community identifier, like http://test.noosfero.net/api/1/i-like-wales/members.json
    • enterprise: used when {module} is a enterprise identifier, like http://test.noosfero.net/api/1/acme/products.json
    • environment: used when {module} is env.
  • {method}: A declared API method for this module on this version by a plugin. If unset, runs the info method.
  • {id}: optional identifier for Resource-Oriented methods (Where the method works as a REST collection)
  • {format}: The output format. That can be json or xml. We will start with JSON.
  • {params}: Method parameters expressed like another controller action extra parameter. For JSONP the API must consider the shared parameter callback, that will work like it does in twitter, wrapping the JSON in a function named with the callback value.

The API infra must implement a methods method for all modules, allowing the API user to know the API support on any Noosfero site.

Examples:
  • GET http://test.noosfero.net/api/1/darth-vader/list_friends.xml
  • GET http://test.noosfero.net/api/last/darth-vader/statuses.json?limit=10&callback=showStatus
  • POST http://test.noosfero.net/api/2/darth-vader/comments (with request data)
  • DELETE http://test.noosfero.net/api/last/darth-vader/comments/123.json
  • GET http://test.noosfero.net/api/1/env/communities.json?callback=show
  • GET http://test.noosfero.net/api/1/env/methods
        {
          methods: {
            communities: { description:"list, find, or retrieve communities", ... },
            add_fun: { description:"add fun thing", ... }
          },
          error: { code: 0, message: "Success" },
          ok: true  // that is the same as "error.num==0", but makes the dev life painless
        }

Implementation

The implementation will start thought the AI:2874 (Products webservice API) and the idea is to make some flexible design and extensible by plugins.

Current implementation features:
  • Plugins can freely add methods for API modules, flowing the defined structure. The control is only against name collision;
  • Methods can be described, allowing the API infra to auto build a simple/easy manual;
  • Default exporting to JSON;
  • Auto wrap JSONP when callback is defined;
  • If the user define a format, the related view will be selected allowing the output to fit to specific interfaces;
  • Auto use the related profile's method when the method with the called name is not defined on the person, community, or enterprise models;
  • Force the user to be unauthenticated guest when the request referrer if from another domain, to block CSRF attacks.

How new methods/resources are added to the API?

Any noosfero plugin can provide API methods. If an environment enables a plugin with provides the method hello to person module on version 1 you will get /api/1/someone/hello working.

As any third part plugin can add a API method, the version at the url is not about the entire collection, but only about the method.

How about "resource" URIs?

Yeah, most methods are exactly the same as a REST resource or a collection when you use it with the id parameter. Example:
  • /api/1/env/enterprises/123id = 123
  • /api/1/env/enterprises/acmeid = acme
  • /api/1/acme — alias to /api/1/acme/info (read only)
  • /api/1/acme/products/456id = 456
  • /api/1/env/products/456id = 456 (related to the same product)
HTTP methods in action:
  • GET /api/1/acme/products — list all ACME products.
  • POST /api/1/acme/products (with data) — create a new product.
  • GET /api/1/acme/products/456 — retrieve the product with id 456.
  • PUT /api/1/acme/products/456 (with data) — update product 456.
  • DELETE /api/1/acme/products/456 — destroy product 456.

The id is planed to fill the REST specification, where each resource has its own URI. The id can be any other unique attribute, like the profile identifier. All that possibilities are easy to implement (i'm not talking about the business rules), but that relays on plugin programmer.

Is this a RESTful API?

This infrastructure is generic RPC friendly and RESTful friendly.

So... Yes (If the plugin programmers make it right).

This API enable the environment to provide:
  • Stateless methods — but do not forbid the programmer to do so if wanted.
  • Uniform interface — that is better when the programmer add the methods on env as resource collections, to simplify the client configuration, but that has a hard standard at all.
    • Use HTTP method as resource action — but that relay totally on the programmer.
  • Cacheable — but that relay totally on the programmer.

As you see, any Noosfero installation can have a RESTful API, but you must to select the right plugins if you care about. Don't worry! Nobody will die if you have some stateful methods on your API, that kind of method will be not used by REST clients.

Also, sometime, the core must to provide provide all REST resources on its API.

Comments

Consider the OCS on this specification http://www.freedesktop.org/wiki/Specifications/open-collaboration-services

-- AurelioAHeckert - 17 May 2011

We should also look at RDF, generic data models for the resources we interface, true RESTfulness vs. compatibility to established social network APIs, and layered security (to let sites decide if they want to give out all information easily to crawlers).

-- JosefSpillner - 28 May 2011

Well, maturing:
  • RDF or XML can be easily replaced by JSON.
  • In a browser we can only use JSONP in a cross-site API usage.
  • There is a fat-less lib for r/w JSON for every language used for building real apps.

We must to consider to not develop unnecessary and fat code for XML responses. We also must consider to use some intelligent API (sub)famework like Rocket Pants or RABL for less pain. Read an article about the creation of a huge API and more.

-- AurelioAHeckert - 11 Jul 2012

Working branch: https://gitlab.com/aurium/noosfero/commits/AI2874-API

-- AurelioAHeckert - 09 Jan 2014

XML Schemas to export data:

-- AurelioAHeckert - 24 Jan 2014

Consider:

-- AurelioAHeckert - 18 Feb 2014
Add comment
You need to login to be able to comment.
 

ActionItemForm edit

Title Noosfero Public API — a web-service API
ActionItemType FeatureItem
Priority Low
Tags
Feature API, Infrastructure, Plugins, SocialNetwork
Plugin
ResponsibleDevelopers AurelioAHeckert
ScheduledFor N/A
AffectsVersion
Status Working
Ticket SAC:
who cares RodrigoSouto, BraulioBhavamitraBO, ValessioBrito, AurelioAHeckert, DanielTygel, DanielBucher
Topic attachments
I Attachment Action Size Date Who Comment
api.rb.txttxt api.rb.txt manage 6.4 K 15 Nov 2013 - 22:48 AurelioAHeckert  
Topic revision: r36 - 11 Mar 2014, AurelioAHeckert

irc Talk with Devs Now!

 
Translations: English
Search on Docs:
   
ActionItem Search:

Copyright © 2007-2018 by the Noosfero contributors
Colivre - Cooperativa de Tecnologias Livres