Coder Social home page Coder Social logo

cakephp-api-datasources's Introduction

Apis Plugin

Since I started going through several restful apis things started to become repitive. I decided to layout my code in a more 'proper ' fashion then.

Installation

Step 1: Clone or download to plugins/apis

Step 2: Add your configuration to database.php and set it to the model

:: database.php ::
var $myapi = array(
	'datasource' => 'Apis.Apis',
	'driver' => 'MyPlugin.MyPlugin' // Example: 'Github.Github'
	
	// These are only required for authenticated requests (write-access)
	'login' => '--Your API Key--',
	'password' => '--Your API Secret--',
);

:: my_model.php ::
var $useDbConfig = 'myapi';

Expanding functionality

Creating a configuration map

[my_plugin]/config/[my_plugin].php

REST paths must be ordered from most specific conditions to least (or none). This is because the map is iterated through until the first path which has all of its required conditions met is found. If a path has no required conditions, it will be used. Optional conditions aren't checked, but are added when building the request.

$config['Apis']['MyPlugin']['hosts'] = array(
	'oauth' => 'api.myplugin.com/login/oauth',
	'rest' => 'api.myplugin.com/v1',
);
$config['Apis']['MyPlugin']['oauth'] = array(
	'authorize' => 'authorize', // Example URI: api.linkedin.com/uas/oauth/authorize
	'request' => 'requestToken',
	'access' => 'accessToken',
	'login' => 'authenticate', // Like authorize, just auto-redirects
	'logout' => 'invalidateToken',
);
$config['Apis']['MyPlugin']['read'] = array(
	// field
	'people' => array(
		// api url
		'people/id=' => array(
			// required conditions
			'id',
		),
		'people/url=' => array(
			'url',
		),
		'people/~' => array(),
	),
	'people-search' => array(
		'people-search' => array(
		// optional conditions the api call can take
			'optional' => array(
				'keywords',
			),
		),
	),
);
$config['Apis']['MyPlugin']['write'] = array(
);
$config['Apis']['MyPlugin']['update'] = array(
);
$config['Apis']['MyPlugin']['delete'] = array(
);

Creating a custom datasource

Try browsing the apis datasource and seeing what automagic functionality you can hook into!

[my_plugin]/models/datasources/apis/[my_plugin].php

Class MyPlugin extends ApisSource {
	// Examples of overriding methods & attributes:
	public $options = array(
		'format'    => 'json',
		'ps'		=> '&', // param separator
		'kvs'		=> '=', // key-value separator
	);
	// Key => Values substitions in the uri-path right before the request is made. Scans uri-path for :keyname
	public $tokens = array();
	// Enable OAuth for the api
	public function __construct($config) {
		$config['method'] = 'OAuth'; // or 'OAuthV2'
		parent::__construct($config);
	}
	// Last minute tweaks
	public function beforeRequest(&$model, $request) {
		$request['header']['x-li-format'] = $this->options['format'];
		return $request;
	}
}

Creating a custom oauth component (recommended approach)

[my_plugin]/controllers/components/[my_plugin].php

App::import('Component', 'Apis.Oauth');
Class MyPluginComponent extends OauthComponent {
	// Override & supplement your methods & attributes
}

On-the-fly customization

Lets say you don't feel like bothering to make a new plugin just to support your api, or the existing plugin doesn't cover enough of the features. Good news! The plugin degrades gracefully and allows you to manually manipulate the request (thanks to NeilCrookes' RESTful plugin).

Simply populate Model->request with any request params you wish and then fire off the related action. You can even continue using the $data & $this->data for save() and update() or pass a 'path' key to find() and it will automagically be injected into your request object.

Adding OAuth Authentication (requires a configuration map)

MyController extends AppController {
	var $components = array(
		'Apis.Oauth' => 'linkedin',
	);
	
	function connect() {
		$this->Oauth->connect();
	}
	
	function linkedin_callback() {
		$this->Oauth->callback();
	}
}

You can also use multiple database configurations

var $components = array(
	'Apis.Oauth' => array(
		'linkedin',
		'github',
		'flickr',
	);
);

However this requires you to specify which config to use before calling authentication methods

function beforeFilter() {
	$this->Oauth->useDbConfig = 'github';
}

Roadmap / Concerns

I'm eager to hear any recommendations or possible solutions.

  • More automagic
  • Better map scanning: I'm not sure of a good way to add map scanning to save(), update() and delete() methods yet since I have little control over the arguments passed to the datasource. It is easy to supplement find() with information and utilize it for processing.
  • Complex query-building versatility: Some APIs have multiple different ways of passing query params. Sometimes within the same request! I still need to flesh out param-building functions and options in the driver so that people extending the datasource have less work.
  • OAuth v2.0 Confirmed support: Github uses v2.0. I updated the component to work accordingly, however I have to test that the HttpSocketOauth can use it.

cakephp-api-datasources's People

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.