Submitted by: skunkich
Posted at: 2011-12-30 16:42:17
See full post and comment: http://9gag.com/gag/1389766
- Seeking Alpha Market Currents
- The Big Picture
- Real Time Economics
- DealBook
- Financial Armageddon
- FT Alphaville
- Zero Hedge
- Naked Capitalism
- Calculated Risk
- Mish’s Global Economic Analysis
An application programming interface (API) is a source code based specification intended to be used as an interface by software components to communicate with each other. An API may include specifications for routines, data structures, object classes, and variables.
An API-Centric Web Application is a web application that basically executes most, if not, all its functionality through API calls.
Consumers are spending more time on mobile apps than on the web for the first time, a new report claims.
Flurry compared its mobile data to stats from comScore and Alexa, and found that in June, consumers spent 81 minutes per day using mobile apps, compared to 74 minutes of web surfing.
The latest data on browser trends from Sitepoint show that more people browse the Web on smartphones than use Internet Explorer 6 and 7 combined. Those two old clunkers have been the bugbears of Web developers for years, requiring sites to degrade as nicely as possible to that least common denominator of browsers. But it’s a new world now; 6.95% of Web activity in November 2011 was on mobile browsers, and only 6.49% was on IE 6 or 7.
This would inevitably lead to more usage of our application, since it can be used anywhere a person wants.
One of the most important architectural changes is that Twitter.com is now a client of our own API. It fetches data from the same endpoints that the mobile site, our apps for iPhone, iPad, Android, and every third-party application use. This shift allowed us to allocate more resources to the API team, generating over 40 patches. In the initial page load and every call from the client, all data is now fetched from a highly optimized JSON fragment cache.
simpletodo_api, and create an index.php file. This index.php file will act as a front controller for the API, so all requests to the API server will be made through this file. Open it up and put the following code inside:<?php
// Define path to data folder
define('DATA_PATH', realpath(dirname(__FILE__).'/data'));
//include our models
include_once 'models/TodoItem.php';
//wrap the whole thing in a try-catch block to catch any wayward exceptions!
try {
//get all of the parameters in the POST/GET request
$params = $_REQUEST;
//get the controller and format it correctly so the first
//letter is always capitalized
$controller = ucfirst(strtolower($params['controller']));
//get the action and format it correctly so all the
//letters are not capitalized, and append 'Action'
$action = strtolower($params['action']).'Action';
//check if the controller exists. if not, throw an exception
if( file_exists("controllers/{$controller}.php") ) {
include_once "controllers/{$controller}.php";
} else {
throw new Exception('Controller is invalid.');
}
//create a new instance of the controller, and pass
//it the parameters from the request
$controller = new $controller($params);
//check if the action exists in the controller. if not, throw an exception.
if( method_exists($controller, $action) === false ) {
throw new Exception('Action is invalid.');
}
//execute the action
$result['data'] = $controller->$action();
$result['success'] = true;
} catch( Exception $e ) {
//catch any exceptions and report the problem
$result = array();
$result['success'] = false;
$result['errormsg'] = $e->getMessage();
}
//echo the result of the API call
echo json_encode($result);
exit();
Controller and Action for the API callController and Action existindex.php file, create three folders: a controllers, models and data folder.Todo.php. This will be our controller for any TODO list related tasks. With the functions we’ll be needing for our TODO application in mind, create the necessary methods for the Todo controller:
<?php
class Todo
{
private $_params;
public function __construct($params)
{
$this->_params = $params;
}
public function createAction()
{
//create a new todo item
}
public function readAction()
{
//read all the todo items
}
public function updateAction()
{
//update a todo item
}
public function deleteAction()
{
//delete a todo item
}
}
action. I’ll provide the code for the createAction method and I’ll leave it up to you to create the code for the other methods. If you’re not in the mood though, you can just download the source code for the demo and copy it from there.
public function createAction()
{
//create a new todo item
$todo = new TodoItem();
$todo->title = $this->_params['title'];
$todo->description = $this->_params['description'];
$todo->due_date = $this->_params['due_date'];
$todo->is_done = 'false';
//pass the user's username and password to authenticate the user
$todo->save($this->_params['username'], $this->_params['userpass']);
//return the todo item in array format
return $todo->toArray();
}
TodoItem.php inside the models folder so we can create the “item creation” code. Take note that I won’t be connecting to a database, rather, I’ll be saving the information into files. It should be relatively easy though to make this work with any database.
<?php
class TodoItem
{
public $todo_id;
public $title;
public $description;
public $due_date;
public $is_done;
public function save($username, $userpass)
{
//get the username/password hash
$userhash = sha1("{$username}_{$userpass}");
if( is_dir(DATA_PATH."/{$userhash}") === false ) {
mkdir(DATA_PATH."/{$userhash}");
}
//if the $todo_id isn't set yet, it means we need to create a new todo item
if( is_null($this->todo_id) || !is_numeric($this->todo_id) ) {
//the todo id is the current time
$this->todo_id = time();
}
//get the array version of this todo item
$todo_item_array = $this->toArray();
//save the serialized array version into a file
$success = file_put_contents(DATA_PATH."/{$userhash}/{$this->todo_id}.txt", serialize($todo_item_array));
//if saving was not successful, throw an exception
if( $success === false ) {
throw new Exception('Failed to save todo item');
}
//return the array version
return $todo_item_array;
}
public function toArray()
{
//return an array version of the todo item
return array(
'todo_id' => $this->todo_id,
'title' => $this->title,
'description' => $this->description,
'due_date' => $this->due_date,
'is_done' => $this->is_done
);
}
}
createAction method calls two functions on the TodoItem model:TodoItem into a file, as well as set the todo_id for the TodoItem if necessaryTodoItem, where the variables are the array’s indexesdata folder, and inside that folder, you should see a file with the following content:createAction() resultAPP ID and APP SECRETAPP ID, let’s say it’s application APP001.
<?php
// Define path to data folder
define('DATA_PATH', realpath(dirname(__FILE__).'/data'));
//Define our id-key pairs
$applications = array(
'APP001' => '28e336ac6c9423d946ba02d19c6a2632', //randomly generated app key
);
//include our models
include_once 'models/TodoItem.php';
//wrap the whole thing in a try-catch block to catch any wayward exceptions!
try {
//*UPDATED*
//get the encrypted request
$enc_request = $_REQUEST['enc_request'];
//get the provided app id
$app_id = $_REQUEST['app_id'];
//check first if the app id exists in the list of applications
if( !isset($applications[$app_id]) ) {
throw new Exception('Application does not exist!');
}
//decrypt the request
$params = json_decode(trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $applications[$app_id], base64_decode($enc_request), MCRYPT_MODE_ECB)));
//check if the request is valid by checking if it's an array and looking for the controller and action
if( $params == false || isset($params->controller) == false || isset($params->action) == false ) {
throw new Exception('Request is not valid');
}
//cast it into an array
$params = (array) $params;
...
...
...
APP KEY. The APP KEY is NEVER sent to the server, it’s only used to hash the request. Additionally, the request can only be decrypted using the APP KEY.APP ID providedAPP ID sentAPP ID and APP SECRET, we can begin programming a front-end client to use the API server.simpletodo_client_browser on your web server’s folder. When that’s done, create an index.php file and put this code inside:
<!DOCTYPE html>
<html>
<head>
<title>SimpleTODO</title>
<link rel="stylesheet" href="css/reset.css" type="text/css" />
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui-1.8.16.custom.min.js"></script>
<style>
body {
padding-top: 40px;
}
#main {
margin-top: 80px;
text-align: center;
}
</style>
</head>
<body>
<div class="topbar">
<div class="fill">
<div class="container">
<a class="brand" href="index.php">SimpleTODO</a>
</div>
</div>
</div>
<div id="main" class="container">
<form class="form-stacked" method="POST" action="login.php">
<div class="row">
<div class="span5 offset5">
<label for="login_username">Username:</label>
<input type="text" id="login_username" name="login_username" placeholder="username" />
<label for="login_password">Password:</label>
<input type="password" id="login_password" name="login_password" placeholder="password" />
</div>
</div>
<div class="actions">
<button type="submit" name="login_submit" class="btn primary large">Login or Register</button>
</div>
</form>
</div>
</body>
</html>
login.php file so we store the username and password inside a session on the client.
<?php
//get the form values
$username = $_POST['login_username'];
$userpass = $_POST['login_password'];
session_start();
$_SESSION['username'] = $username;
$_SESSION['userpass'] = $userpass;
header('Location: todo.php');
exit();
todo.php, where we start interacting with the API server. Before we start coding the todo.php file though, let’s first create an ApiCaller class, which will encapsulate all the API calling methods we’ll need, including encrypting the requests.apicaller.php and put the following inside:
<?php
class ApiCaller
{
//some variables for the object
private $_app_id;
private $_app_key;
private $_api_url;
//construct an ApiCaller object, taking an
//APP ID, APP KEY and API URL parameter
public function __construct($app_id, $app_key, $api_url)
{
$this->_app_id = $app_id;
$this->_app_key = $app_key;
$this->_api_url = $api_url;
}
//send the request to the API server
//also encrypts the request, then checks
//if the results are valid
public function sendRequest($request_params)
{
//encrypt the request parameters
$enc_request = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->_app_key, json_encode($request_params), MCRYPT_MODE_ECB));
//create the params array, which will
//be the POST parameters
$params = array();
$params['enc_request'] = $enc_request;
$params['app_id'] = $this->_app_id;
//initialize and setup the curl handler
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->_api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($params));
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
//execute the request
$result = curl_exec($ch);
//json_decode the result
$result = @json_decode($result);
//check if we're able to json_decode the result correctly
if( $result == false || isset($result['success']) == false ) {
throw new Exception('Request was not correct');
}
//if there was an error in the request, throw an exception
if( $result['success'] == false ) {
throw new Exception($result['errormsg']);
}
//if everything went great, return the data
return $result['data'];
}
}
ApiCaller class to send requests to our API server. This way, all the necessary encryption and cURL initialization code will be in one place, and we won’t have to repeat our code.__construct function takes in three parameters:APP ID for the client (which is APP001 for the browser client)APP KEY for the client (which is 28e336ac6c9423d946ba02d19c6a2632 for the browser client)http://localhost/simpletodo_api/sendRequest() function:mcrypt library in the same manner that the API server decrypts it$_POST parameters to be sent to the API servertodo.php page. First off, let’s create some code to retrieve the current list of todo items for the user nikko with the password test1234 (this is the user/password combination we used earlier to test the API server).
<?php
session_start();
include_once 'apicaller.php';
$apicaller = new ApiCaller('APP001', '28e336ac6c9423d946ba02d19c6a2632', 'http://localhost/simpletodo_api/');
$todo_items = $apicaller->sendRequest(array(
'controller' => 'todo',
'action' => 'read',
'username' => $_SESSION['username'],
'userpass' => $_SESSION['userpass']
));
echo '';
var_dump($todo_items);
index.php page, login as nikko/test1234, and you should see a var_dump() of the TODO item we created earlier.username and userpass in the $_SESSIONApiCaller class, giving it the APP ID, APP KEY and the URL of the API serversendRequest() methodtodo.php code. Don’t forget to remove the var_dump()!
<!DOCTYPE html>
<html>
<head>
<title>SimpleTODO</title>
<link rel="stylesheet" href="css/reset.css" type="text/css" />
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="css/flick/jquery-ui-1.8.16.custom.css" type="text/css" />
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui-1.8.16.custom.min.js"></script>
<style>
body {
padding-top: 40px;
}
#main {
margin-top: 80px;
}
.textalignright {
text-align: right;
}
.marginbottom10 {
margin-bottom: 10px;
}
#newtodo_window {
text-align: left;
display: none;
}
</style>
<script>
$(document).ready(function() {
$("#todolist").accordion({
collapsible: true
});
$(".datepicker").datepicker();
$('#newtodo_window').dialog({
autoOpen: false,
height: 'auto',
width: 'auto',
modal: true
});
$('#newtodo').click(function() {
$('#newtodo_window').dialog('open');
});
});
</script>
</head>
<body>
<div class="topbar">
<div class="fill">
<div class="container">
<a class="brand" href="index.php">SimpleTODO</a>
</div>
</div>
</div>
<div id="main" class="container">
<div class="textalignright marginbottom10">
<span id="newtodo" class="btn info">Create a new TODO item</span>
<div id="newtodo_window" title="Create a new TODO item">
<form method="POST" action="new_todo.php">
<p>Title:<br /><input type="text" class="title" name="title" placeholder="TODO title" /></p>
<p>Date Due:<br /><input type="text" class="datepicker" name="due_date" placeholder="MM/DD/YYYY" /></p>
<p>Description:<br /><textarea class="description" name="description"></textarea></p>
<div class="actions">
<input type="submit" value="Create" name="new_submit" class="btn primary" />
</div>
</form>
</div>
</div>
<div id="todolist">
<?php foreach($todo_items as $todo): ?>
<h3><a href="#"><?php echo $todo->title; ?></a></h3>
<div>
<form method="POST" action="update_todo.php">
<div class="textalignright">
<a href="delete_todo.php?todo_id=<?php echo $todo->todo_id; ?>">Delete</a>
</div>
<div>
<p>Date Due:<br /><input type="text" id="datepicker_<?php echo $todo->todo_id; ?>" class="datepicker" name="due_date" value="12/09/2011" /></p>
<p>Description:<br /><textarea class="span8" id="description_<?php echo $todo->todo_id; ?>" class="description" name="description"><?php echo $todo->description; ?></textarea></p>
</div>
<div class="textalignright">
<?php if( $todo->is_done == 'false' ): ?>
<input type="hidden" value="false" name="is_done" />
<input type="submit" class="btn" value="Mark as Done?" name="markasdone_button" />
<?php else: ?>
<input type="hidden" value="true" name="is_done" />
<input type="button" class="btn success" value="Done!" name="done_button" />
<?php endif; ?>
<input type="hidden" value="<?php echo $todo->todo_id; ?>" name="todo_id" />
<input type="hidden" value="<?php echo $todo->title; ?>" name="title" />
<input type="submit" class="btn primary" value="Save Changes" name="update_button" />
</div>
</form>
</div>
<?php endforeach; ?>
</div>
</div>
</body>
</html>
new_todo.php, which will call the todo/create API call to create a new TODO item. Creating the other pages (update_todo.php and delete_todo.php) should be very similar to this one, so I’ll leave it up to you to create those. Open up new_todo.php and add the following code:
<?php
session_start();
include_once 'apicaller.php';
$apicaller = new ApiCaller('APP001', '28e336ac6c9423d946ba02d19c6a2632', 'http://localhost/simpletodo_api/');
$new_item = $apicaller->sendRequest(array(
'controller' => 'todo',
'action' => 'create',
'title' => $_POST['title'],
'due_date' => $_POST['due_date'],
'description' => $_POST['description'],
'username' => $_SESSION['username'],
'userpass' => $_SESSION['userpass']
));
header('Location: todo.php');
exit();
?>
new_todo.php page uses the ApiCaller again to facilitate the sending the todo/create request to the API server. This basically does the same thing as before:$username and $userpass saved in the $_SESSIONApiCaller class, giving it the APP ID, APP KEY and the URL of the API serversendRequest() methodtodo.php
We must continue learning about the latest technologies.
Set aside some time to also focus on existing languages and software.
Call it engaging, call it networking, call it whatever your want.
The most beneficial comments are the ones that hurt your feelings.
We are the martyrs of the web.
Over 1 trillion videos were watched on Youtube this past year.
I don’t think you’ll ever have an issue with over-documentation.
The manager of Tuts+ Premium, Skellie, recently opened the Passive Income Author blog, where you’ll find great information on self-publishing.