Skip to content

Instantly share code, notes, and snippets.

@luniki
Created February 24, 2012 09:46
Show Gist options
  • Save luniki/1899795 to your computer and use it in GitHub Desktop.
Save luniki/1899795 to your computer and use it in GitHub Desktop.
OAuthAPIProvider

Stud.IP Restful APIs mit OAuth

Ziel ist es, ein Plugin (oder Kernfunktionalität) anzubieten, dass Restful Webservices, die mit OAuth abgesichert sind, für 3rd-party-tools zugänglich macht.

Die APIs sollen (auch) als Plugins zuschaltbar sein. Dazu wird zunächst ein Verwaltungsplugin "OAuthAPIProvider" geschaffen, dass einen neuen Plugintyp einführt, den API-liefernde Plugin implementieren müssen.

OAuthAPIProvider nimmt alle API-Zugriffe entgegen, authorisiert mit OAuth und leitet den Request dann an das passende Plugin weiter.

Das API-Plugin-Interface könnte zB so aussehen:

interface APIPlugin {
    function routes($router);
}

OAuthAPIProvider such sich alle APIPlugins und ruft an ihnen #routes auf. Mit Hilfe dieser Resultate entscheidet er dann, welches Plugin den Request weiterverarbeitet.

Dabei sehe ich derzeit zwei Lösungen.

Lösung a. Slim-like

Als Beispiel verwende ich Slim. Das kann man aber auch mit Trails o.ä. machen. Slim dient hier also nur als Beispiel.

OAuthAPIProvider sieht dann ungefähr so aus:

$slim = new Slim();
$plugins = PluginEngine::getPlugins("APIPlugin");

foreach ($plugins as $plugin) {
    $plugin->routes($slim);
}

$slim->run();

(An der Stelle muss natürlich noch OAuth mit hinein.)

Im Plugin würde man das dann so machen:

function routes($router)
{
    $router->get('/news/:range', function ($range) {
        echo "News for $range";
    });
}

Lösung b. Trails-Dispatcher ohne Dateisystem

In diesem Beispiel baut man den Trails-Dispatcher so um, dass er beim #parse des Requests nicht im Dateisystem sucht, sondern in einer Baumstruktur, die von den APIPlugins zusammengebaut wird.

OAuthAPIProvider wird in dem Fall einfach so etwas tun:

$dispatcher = new RoutingDispatcher(...);

$routes = array_flatten(PluginEngine::sendMessage("APIPlugin", "routes");
$dispatcher->set_routes($routes);

$dispatcher->dispatch($request_uri);

RoutingDispatcher findet den das längste Common Prefix in den $routes (das ist billig: O(log n)) und leitet dann den kompletten Request an das Plugin weiter. Das Plugin selber baut sich zB einen Standard-Trails_Dispatcher und leitet den Request an diesen weiter.

@tleilax
Copy link

tleilax commented Feb 27, 2012

Auf den ersten Blick gefällt mir die Slim-Lösung eher. Wirkt irgendwie kompakter.

Könnte Trails das auch momentan in dieser Form abdecken? Falls nicht, lohnt es sich, da Zeit reinzustecken, wenn bspw. Slim schon eh alles mitbringt, was wir brauchen? Wir müssen das Rad ja nicht neu erfinden...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment