Spanish (Español) translation by CYC (you can also view the original English article)
¿Estás planeando comenzar a trabajar en una nueva aplicación web? En este tutorial, discutiremos cómo crear una aplicación web centrada en API y explicaremos por qué esto es esencial en el mundo multiplataforma actual.
Introducción
¿API?
Para aquellos que no están familiarizados con el término, API es la abreviatura de Application Programming Interface. De acuerdo con Wikipedia:
Una interfaz de programación de aplicaciones (API) es una especificación basada en el código fuente que los componentes de software deben usar como interfaz para comunicarse entre ellos. Una API puede incluir especificaciones para rutinas, estructuras de datos, clases de objetos y variables.
En términos más simples, una API se refiere a un conjunto de funciones integradas en una aplicación, que pueden ser utilizadas por otras aplicaciones (o por sí mismas, como veremos más adelante) para interactuar con la aplicación. Una API es una excelente manera de exponer la funcionalidad de una aplicación a aplicaciones externas de forma segura, ya que todas las funciones que estas aplicaciones externas pueden hacer están limitadas por la funcionalidad expuesta en la API.
¿Qué es una aplicación web "centrada en la API"?
Una aplicación web centrada en API es una aplicación web que básicamente ejecuta la mayoría, si no, toda su funcionalidad a través de llamadas API.
Una aplicación web centrada en API es una aplicación web que básicamente ejecuta la mayoría, si no, toda su funcionalidad a través de llamadas API. Por ejemplo, si vas a iniciar sesión en un usuario, debes enviar tus credenciales a la API, y la API te devolverá un resultado que indica si el usuario proporcionó la combinación correcta de usuario-contraseña.
Otra característica de una aplicación web centrada en API es que la API siempre será sin estado, lo que significa que no puede reconocer llamadas de API por sesión. Dado que las llamadas a la API se realizarán generalmente a través del código de servidor, será difícil implementar el manejo de la sesión, ya que generalmente no hay cookies involucradas en eso. Esta limitación es realmente buena: esto "obliga" a un desarrollador a crear una API que no funciona en función del estado del usuario actual, sino más bien de la funcionalidad, lo que a su vez facilita la prueba, ya que el estado actual de un usuario no necesita ser recreado
¿Por qué pasar todo este problema?
Como desarrolladores web, hemos visto evolucionar la tecnología de primera mano. Es de conocimiento común que las personas de hoy no solo usan aplicaciones a través de un navegador, sino a través de otros dispositivos, como teléfonos móviles y tabletas. Por ejemplo, este artículo en Mashable, titulado "Los consumidores ahora gastan más tiempo en aplicaciones móviles que la Web", afirma:
Los consumidores están pasando más tiempo en aplicaciones móviles que en la web por primera vez, según un nuevo informe.
Flurry comparó sus datos móviles con las estadísticas de comScore y Alexa, y descubrió que, en junio, los consumidores pasaron 81 minutos al día usando aplicaciones móviles, en comparación con los 74 minutos de navegación en la web.
Aquí hay un artículo más reciente de ReadWriteWeb, titulado "Más personas navegan en dispositivos móviles que utilizan IE6 e IE7 combinados":
Los últimos datos sobre las tendencias de los navegadores de Sitepoint muestran que más personas navegan por la Web en teléfonos inteligentes que usan Internet Explorer 6 y 7 combinados. Esos dos viejos cacharros han sido las pesadillas de los desarrolladores web durante años, lo que exige que los sitios se degraden lo mejor posible al mínimo común denominador de los navegadores. Pero es un mundo nuevo ahora; 6.95% de la actividad web en noviembre de 2011 fue en navegadores móviles, y solo 6.49% fue en IE 6 o 7.
Como podemos ver claramente, cada vez más personas obtienen sus noticias de lugares alternativos, específicamente dispositivos móviles.
¿Qué tiene esto que ver conmigo al crear una aplicación web centrada en API?
Esto conduciría inevitablemente a un mayor uso de nuestra aplicación, ya que se puede usar en cualquier lugar que desee una persona.
Una de las principales ventajas de crear una aplicación centrada en API es que te ayuda a crear funcionalidades que pueden usar CUALQUIER dispositivo, ya sea un navegador, un teléfono móvil, una tableta o incluso una aplicación de escritorio. Todo lo que necesitas hacer es crear la API de tal manera que todos estos dispositivos se puedan comunicar con ella, y ¡listo! ¡Habrás creado una aplicación centralizada que puede tomar el input y ejecutar la funcionalidad desde cualquier dispositivo que tenga una persona!



Diagrama de una aplicación centrada en API
Al crear una aplicación de esta manera, podemos aprovechar fácilmente los diferentes medios utilizados por diferentes personas. Esto conduciría inevitablemente a un mayor uso de una aplicación, ya que puede utilizarse en cualquier lugar que desee una persona.
Para aclarar el punto, aquí hay un artículo sobre el nuevo sitio web rediseñado de Twitter, que nos dice cómo ahora usan su API para impulsar Twitter.com, esencialmente haciendo que se centre en una API:
Uno de los cambios arquitectónicos más importantes es que Twitter.com ahora es cliente de nuestra propia API. Obtiene datos de los mismos puntos finales que usa el sitio móvil, nuestras aplicaciones para iPhone, iPad, Android y todas las aplicaciones de terceros. Este cambio nos permitió asignar más recursos al equipo de API, generando más de 40 parches. En la carga de la página inicial y cada llamada del cliente, todos los datos ahora se extraen de un caché de fragmentos JSON altamente optimizado.
En este tutorial, crearemos una aplicación de lista TODO simple que sea API-Centric y crearemos un cliente de front-end en el navegador que interactúe con nuestra aplicación de listas TODO. Al final, conocerás las partes integrales de una aplicación centrada en la API y, al mismo tiempo, cómo facilitar la comunicación segura entre las dos. Con eso en mente, ¡comencemos!
Paso 1: Planificar las funciones de la aplicación
La aplicación TODO que construiremos en este tutorial tendrá las funciones CRUD básicas:
- Crear elementos en el TODO
- Read, de "Leer" los elementos del TODO
- Update, de "Actualizar" los elementos del TODO (renombrar, marcar como hecho, marcar como deshecho)
- Delete, de "Eliminar" los elementos del TODO
Cada artículo TODO tendrá:
- un título
- Una fecha
- una descripción
- una bandera para indicar si se ha completado el elemento del TODO
Vamos a simular también la aplicación para que tengamos una guía sobre cómo se verá después:



Maquetado simple del TODO
Paso 2: Crea el servidor API
Dado que estamos desarrollando una aplicación centrada en API, crearemos dos "proyectos": el servidor API y el cliente front-end. Comencemos creando primero el servidor API.
En la carpeta de tu servidor web, crea una carpeta llamada simpletodo_api, y crea un archivo index.php. Este archivo index.php actuará como un controlador frontal para la API, por lo que todas las solicitudes al servidor API se realizarán a través de este archivo. Ábrelo y pon el siguiente código dentro:
1 |
|
2 |
<?php
|
3 |
// Define path to data folder
|
4 |
define('DATA_PATH', realpath(dirname(__FILE__).'/data')); |
5 |
|
6 |
//include our models
|
7 |
include_once 'models/TodoItem.php'; |
8 |
|
9 |
//wrap the whole thing in a try-catch block to catch any wayward exceptions!
|
10 |
try { |
11 |
//get all of the parameters in the POST/GET request
|
12 |
$params = $_REQUEST; |
13 |
|
14 |
//get the controller and format it correctly so the first
|
15 |
//letter is always capitalized
|
16 |
$controller = ucfirst(strtolower($params['controller'])); |
17 |
|
18 |
//get the action and format it correctly so all the
|
19 |
//letters are not capitalized, and append 'Action'
|
20 |
$action = strtolower($params['action']).'Action'; |
21 |
|
22 |
//check if the controller exists. if not, throw an exception
|
23 |
if( file_exists("controllers/{$controller}.php") ) { |
24 |
include_once "controllers/{$controller}.php"; |
25 |
} else { |
26 |
throw new Exception('Controller is invalid.'); |
27 |
}
|
28 |
|
29 |
//create a new instance of the controller, and pass
|
30 |
//it the parameters from the request
|
31 |
$controller = new $controller($params); |
32 |
|
33 |
//check if the action exists in the controller. if not, throw an exception.
|
34 |
if( method_exists($controller, $action) === false ) { |
35 |
throw new Exception('Action is invalid.'); |
36 |
}
|
37 |
|
38 |
//execute the action
|
39 |
$result['data'] = $controller->$action(); |
40 |
$result['success'] = true; |
41 |
|
42 |
} catch( Exception $e ) { |
43 |
//catch any exceptions and report the problem
|
44 |
$result = array(); |
45 |
$result['success'] = false; |
46 |
$result['errormsg'] = $e->getMessage(); |
47 |
}
|
48 |
|
49 |
//echo the result of the API call
|
50 |
echo json_encode($result); |
51 |
exit(); |
Lo que esencialmente hemos construido aquí es un controlador frontal simple que hace lo siguiente:
- Aceptar una llamada API con cualquier cantidad de parámetros
- Extraer el
Controllery elActionpara la llamada API - Realizar las comprobaciones necesarias para asegurarse de que el
Controllery elActionexisten - Ejecutar la llamada a la API
- Capturar errores, si hay alguno
- Enviar un resultado a la persona que llama
Además del archivo index.php, crea tres carpetas: controllers, models y data
- La carpeta controllers contendrá todos los controladores que usaremos para el servidor API. Lo construiremos utilizando la arquitectura MVC para que la estructura del servidor API esté más limpia y organizada.
- La carpeta models contendrá todos los modelos de datos para el servidor API.
- La carpeta data estará donde el servidor API guarda cualquier información
Dirígete a la carpeta controllers y crea un archivo llamado Todo.php. Este será nuestro controlador para cualquier tarea relacionada con la lista TODO. Con las funciones que necesitaremos para nuestra aplicación TODO en mente, crea los métodos necesarios para el controlador Todo:
1 |
|
2 |
|
3 |
<?php
|
4 |
class Todo |
5 |
{
|
6 |
private $_params; |
7 |
|
8 |
public function __construct($params) |
9 |
{
|
10 |
$this->_params = $params; |
11 |
}
|
12 |
|
13 |
public function createAction() |
14 |
{
|
15 |
//create a new todo item
|
16 |
}
|
17 |
|
18 |
public function readAction() |
19 |
{
|
20 |
//read all the todo items
|
21 |
}
|
22 |
|
23 |
public function updateAction() |
24 |
{
|
25 |
//update a todo item
|
26 |
}
|
27 |
|
28 |
public function deleteAction() |
29 |
{
|
30 |
//delete a todo item
|
31 |
}
|
32 |
}
|
Ahora, agrega la funcionalidad necesaria a cada action. Proporcionaré el código para el método createAction y dejaré que crees el código para los otros métodos. Si no estás de humor, puedes descargar el código fuente de la demostración y copiarla desde allí.
1 |
|
2 |
|
3 |
public function createAction() |
4 |
{
|
5 |
//create a new todo item
|
6 |
$todo = new TodoItem(); |
7 |
$todo->title = $this->_params['title']; |
8 |
$todo->description = $this->_params['description']; |
9 |
$todo->due_date = $this->_params['due_date']; |
10 |
$todo->is_done = 'false'; |
11 |
|
12 |
//pass the user's username and password to authenticate the user
|
13 |
$todo->save($this->_params['username'], $this->_params['userpass']); |
14 |
|
15 |
//return the todo item in array format
|
16 |
return $todo->toArray(); |
17 |
}
|
Crea un archivo llamado TodoItem.php dentro de la carpeta models para que podamos crear el código de "creación de elementos". Ten en cuenta que no me conectaré a una base de datos, sino que guardaré la información en archivos. Sin embargo, debería ser relativamente fácil hacer que esto funcione con cualquier base de datos.
1 |
|
2 |
|
3 |
<?php
|
4 |
class TodoItem |
5 |
{
|
6 |
public $todo_id; |
7 |
public $title; |
8 |
public $description; |
9 |
public $due_date; |
10 |
public $is_done; |
11 |
|
12 |
public function save($username, $userpass) |
13 |
{
|
14 |
//get the username/password hash
|
15 |
$userhash = sha1("{$username}_{$userpass}"); |
16 |
if( is_dir(DATA_PATH."/{$userhash}") === false ) { |
17 |
mkdir(DATA_PATH."/{$userhash}"); |
18 |
}
|
19 |
|
20 |
//if the $todo_id isn't set yet, it means we need to create a new todo item
|
21 |
if( is_null($this->todo_id) || !is_numeric($this->todo_id) ) { |
22 |
//the todo id is the current time
|
23 |
$this->todo_id = time(); |
24 |
}
|
25 |
|
26 |
//get the array version of this todo item
|
27 |
$todo_item_array = $this->toArray(); |
28 |
|
29 |
//save the serialized array version into a file
|
30 |
$success = file_put_contents(DATA_PATH."/{$userhash}/{$this->todo_id}.txt", serialize($todo_item_array)); |
31 |
|
32 |
//if saving was not successful, throw an exception
|
33 |
if( $success === false ) { |
34 |
throw new Exception('Failed to save todo item'); |
35 |
}
|
36 |
|
37 |
//return the array version
|
38 |
return $todo_item_array; |
39 |
}
|
40 |
|
41 |
public function toArray() |
42 |
{
|
43 |
//return an array version of the todo item
|
44 |
return array( |
45 |
'todo_id' => $this->todo_id, |
46 |
'title' => $this->title, |
47 |
'description' => $this->description, |
48 |
'due_date' => $this->due_date, |
49 |
'is_done' => $this->is_done |
50 |
);
|
51 |
}
|
52 |
}
|
El método createAction llama a dos funciones en el modelo TodoItem:
- save() - Esto guarda el
TodoItemen un archivo, así como establece eltodo_idpara elTodoItemsi es necesario - toArray () - Esto devuelve una versión de matriz de
TodoItem, donde las variables son los índices de la matriz
Como se llama a la API a través de solicitudes HTTP, probemos esa llamada API llamándola a través del navegador:
Si todo funcionó, deberías ver una nueva carpeta dentro de la carpeta data, y dentro de esa carpeta, deberías ver un archivo con el siguiente contenido:



Resultado
createAction() ¡Felicidades! ¡Creaste con éxito un servidor API y has realizado una llamada API!
Paso 3: Asegura el servidor API con un APP ID y un APP SECRET
Actualmente, el servidor API está configurado para aceptar TODAS las solicitudes API. Tendremos que limitarlo solo a nuestras propias aplicaciones, para garantizar que solo nuestros clientes front-end puedan realizar solicitudes API. Alternativamente, puedes crear un sistema en el que los usuarios puedan crear sus propias aplicaciones que tengan acceso a tu servidor API, de forma similar a cómo funcionan las aplicaciones de Facebook y Twitter.
Comienza creando un conjunto de pares de claves de id para los clientes que usarán el servidor API. Como esto es solo una demostración, podemos usar cualquier cadena aleatoria de 32 caracteres. Para la APP ID, digamos que es la aplicación APP001.
Abre el archivo index.php nuevamente y luego actualízalo con el siguiente código:
1 |
|
2 |
|
3 |
<?php
|
4 |
// Define path to data folder
|
5 |
define('DATA_PATH', realpath(dirname(__FILE__).'/data')); |
6 |
|
7 |
//Define our id-key pairs
|
8 |
$applications = array( |
9 |
'APP001' => '28e336ac6c9423d946ba02d19c6a2632', //randomly generated app key |
10 |
);
|
11 |
//include our models
|
12 |
include_once 'models/TodoItem.php'; |
13 |
|
14 |
//wrap the whole thing in a try-catch block to catch any wayward exceptions!
|
15 |
try { |
16 |
//*UPDATED*
|
17 |
//get the encrypted request
|
18 |
$enc_request = $_REQUEST['enc_request']; |
19 |
|
20 |
//get the provided app id
|
21 |
$app_id = $_REQUEST['app_id']; |
22 |
|
23 |
//check first if the app id exists in the list of applications
|
24 |
if( !isset($applications[$app_id]) ) { |
25 |
throw new Exception('Application does not exist!'); |
26 |
}
|
27 |
|
28 |
//decrypt the request
|
29 |
$params = json_decode(trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $applications[$app_id], base64_decode($enc_request), MCRYPT_MODE_ECB))); |
30 |
|
31 |
//check if the request is valid by checking if it's an array and looking for the controller and action
|
32 |
if( $params == false || isset($params->controller) == false || isset($params->action) == false ) { |
33 |
throw new Exception('Request is not valid'); |
34 |
}
|
35 |
|
36 |
//cast it into an array
|
37 |
$params = (array) $params; |
38 |
...
|
39 |
...
|
40 |
...
|
Lo que hemos hecho aquí es en realidad implementar una forma muy simple de autenticar a nuestros clientes front-end utilizando un sistema similar a la autenticación de clave pública-privada. Básicamente, aquí está el desglose paso a paso de cómo ocurre la autenticación:



Encriptación de clave pública
- se realiza una llamada API, en ella se proporciona $app_id y $enc_request.
- el valor de $enc_request son los parámetros de llamada API, cifrados mediante
APP KEY. LaAPP KEYNUNCA se envía al servidor, solo se utiliza para actualizar la solicitud. Además, la solicitud solo se puede descifrar utilizando laAPP KEY. - una vez que la llamada API llega al servidor de la API, se verificará su propia lista de aplicaciones para la
APP IDproporcionada - cuando se encuentra, el servidor API intenta descifrar la solicitud utilizando la clave que coincide con la
APP IDenviada - si fue exitoso para descifrarlo, entonces continúa con el programa
Ahora que el servidor API está protegido con una APP ID y una APP SECRET, podemos comenzar a programar un cliente de aplicaciones para el servidor API.
Paso 4: Crear el navegador cliente Front-end
Comenzaremos por configurar una nueva carpeta para el cliente front-end. Crea una carpeta llamada simpletodo_client_browser en la carpeta de tu servidor web. Cuando hayas terminado, crea un archivo index.php y coloca este código dentro:
1 |
|
2 |
|
3 |
<!DOCTYPE html>
|
4 |
<html>
|
5 |
<head>
|
6 |
<title>SimpleTODO</title> |
7 |
|
8 |
<link rel="stylesheet" href="css/reset.css" type="text/css" /> |
9 |
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" /> |
10 |
|
11 |
<script src="js/jquery.min.js"></script> |
12 |
<script src="js/jquery-ui-1.8.16.custom.min.js"></script> |
13 |
|
14 |
<style>
|
15 |
body { |
16 |
padding-top: 40px; |
17 |
}
|
18 |
#main { |
19 |
margin-top: 80px; |
20 |
text-align: center; |
21 |
}
|
22 |
</style>
|
23 |
</head>
|
24 |
<body>
|
25 |
<div class="topbar"> |
26 |
<div class="fill"> |
27 |
<div class="container"> |
28 |
<a class="brand" href="index.php">SimpleTODO</a> |
29 |
</div>
|
30 |
</div>
|
31 |
</div>
|
32 |
<div id="main" class="container"> |
33 |
<form class="form-stacked" method="POST" action="login.php"> |
34 |
<div class="row"> |
35 |
<div class="span5 offset5"> |
36 |
<label for="login_username">Username:</label> |
37 |
<input type="text" id="login_username" name="login_username" placeholder="username" /> |
38 |
|
39 |
<label for="login_password">Password:</label> |
40 |
<input type="password" id="login_password" name="login_password" placeholder="password" /> |
41 |
|
42 |
</div>
|
43 |
</div>
|
44 |
<div class="actions"> |
45 |
<button type="submit" name="login_submit" class="btn primary large">Login or Register</button> |
46 |
</div>
|
47 |
</form>
|
48 |
</div>
|
49 |
</body>
|
50 |
</html>
|
Eso debería verse más o menos así:



Página de inicio de sesión del SimpleDODO
Ten en cuenta que he incluido 2 archivos JavaScript y 2 archivos CSS aquí:
- reset.css es tu secuencia de comandos estándar de restablecimiento de CSS. Uso el restablecimiento css meyerweb.com.
- bootstrap.min.css es el Twitter Bootstrap
- jquery.min.js es la última biblioteca jQuery
- jquery-ui-1.8.16.custom.min.js es la última biblioteca jQuery UI
A continuación, vamos a crear el archivo login.php para que guardemos el nombre de usuario y la contraseña dentro de una sesión en el cliente.
1 |
|
2 |
|
3 |
<?php
|
4 |
//get the form values
|
5 |
$username = $_POST['login_username']; |
6 |
$userpass = $_POST['login_password']; |
7 |
|
8 |
|
9 |
session_start(); |
10 |
$_SESSION['username'] = $username; |
11 |
$_SESSION['userpass'] = $userpass; |
12 |
header('Location: todo.php'); |
13 |
exit(); |
Aquí, simplemente iniciamos una sesión para el usuario, basada en la combinación de nombre de usuario y contraseña que el usuario proporcionará. Esto actúa como una simple combinación de teclas, que permitirá al usuario acceder a los elementos TODO almacenados para una combinación específica de ambos, el nombre de usuario y la contraseña. Luego, redirigimos a todo.php, donde comenzamos a interactuar con el servidor API. Sin embargo, antes de comenzar a codificar el archivo todo.php, primero debemos crear una clase llamada ApiCaller, que encapsulará todos los métodos de llamadas API que necesitaremos, incluido el cifrado de las solicitudes.
Crea apicaller.php y pon lo siguiente dentro:
1 |
|
2 |
|
3 |
<?php
|
4 |
class ApiCaller |
5 |
{
|
6 |
//some variables for the object
|
7 |
private $_app_id; |
8 |
private $_app_key; |
9 |
private $_api_url; |
10 |
|
11 |
//construct an ApiCaller object, taking an
|
12 |
//APP ID, APP KEY and API URL parameter
|
13 |
public function __construct($app_id, $app_key, $api_url) |
14 |
{
|
15 |
$this->_app_id = $app_id; |
16 |
$this->_app_key = $app_key; |
17 |
$this->_api_url = $api_url; |
18 |
}
|
19 |
|
20 |
//send the request to the API server
|
21 |
//also encrypts the request, then checks
|
22 |
//if the results are valid
|
23 |
public function sendRequest($request_params) |
24 |
{
|
25 |
//encrypt the request parameters
|
26 |
$enc_request = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->_app_key, json_encode($request_params), MCRYPT_MODE_ECB)); |
27 |
|
28 |
//create the params array, which will
|
29 |
//be the POST parameters
|
30 |
$params = array(); |
31 |
$params['enc_request'] = $enc_request; |
32 |
$params['app_id'] = $this->_app_id; |
33 |
|
34 |
//initialize and setup the curl handler
|
35 |
$ch = curl_init(); |
36 |
curl_setopt($ch, CURLOPT_URL, $this->_api_url); |
37 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
38 |
curl_setopt($ch, CURLOPT_POST, count($params)); |
39 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $params); |
40 |
|
41 |
//execute the request
|
42 |
$result = curl_exec($ch); |
43 |
|
44 |
//json_decode the result
|
45 |
$result = @json_decode($result); |
46 |
|
47 |
//check if we're able to json_decode the result correctly
|
48 |
if( $result == false || isset($result['success']) == false ) { |
49 |
throw new Exception('Request was not correct'); |
50 |
}
|
51 |
|
52 |
//if there was an error in the request, throw an exception
|
53 |
if( $result['success'] == false ) { |
54 |
throw new Exception($result['errormsg']); |
55 |
}
|
56 |
|
57 |
//if everything went great, return the data
|
58 |
return $result['data']; |
59 |
}
|
60 |
}
|
Usaremos la clase ApiCaller para enviar solicitudes a nuestro servidor API. De esta forma, todo el cifrado necesario y el código de inicialización de cURL estarán en un solo lugar, y no tendremos que repetir nuestro código.
- la función
__constructtiene tres parámetros:- $app_id: la
APP IDpara el cliente (que es APP001 para el cliente del navegador) - $app_key - la
APP KEYpara el cliente (que es 28e336ac6c9423d946ba02d19c6a2632 para el cliente del navegador) - $api_url: la URL del servidor API, que es
http://localhost/simpletodo_api/
- $app_id: la
- la función
sendRequest():- encripta los parámetros de solicitud usando la biblioteca
mcryptde la misma manera que el servidor API lo descifra - genera los parámetros
$_POSTque se enviarán al servidor API - ejecuta la llamada API a través de cURL
- verifica que el resultado de la llamada API fue exitoso o no
- devuelve los datos cuando todo salió según el plan
- encripta los parámetros de solicitud usando la biblioteca
Ahora, comencemos con la página todo.php. Primero, vamos a crear un código para recuperar la lista actual de artículos pendientes para el usuario nikko con la contraseña test1234 (esta es la combinación de usuario / contraseña que usamos antes para probar el servidor API).
1 |
|
2 |
|
3 |
<?php
|
4 |
session_start(); |
5 |
include_once 'apicaller.php'; |
6 |
|
7 |
$apicaller = new ApiCaller('APP001', '28e336ac6c9423d946ba02d19c6a2632', 'http://localhost/simpletodo_api/'); |
8 |
|
9 |
$todo_items = $apicaller->sendRequest(array( |
10 |
'controller' => 'todo', |
11 |
'action' => 'read', |
12 |
'username' => $_SESSION['username'], |
13 |
'userpass' => $_SESSION['userpass'] |
14 |
));
|
15 |
|
16 |
echo ''; |
17 |
var_dump($todo_items); |
Ve a la página index.php, inicia sesión como nikko/test1234, y deberías ver un var_dump() del elemento TODO que creamos anteriormente.
¡Felicitaciones, has realizado una llamada API al servidor API con éxito! En este código, tenemos:
- comenzar la sesión, así que tenemos acceso al
usernameyuserpassen$_SESSION - instanciar una nueva clase
ApiCaller, dándole laAPP ID, laAPP SECRETy la URL del servidor API - enviar una solicitud a través del método
sendRequest()
Ahora, volvamos a formatear los datos para que se vea mejor. Agrega el siguiente código HTML en todo.php. ¡No olvides eliminar el var_dump()!
1 |
|
2 |
|
3 |
<!DOCTYPE html>
|
4 |
<html>
|
5 |
<head>
|
6 |
<title>SimpleTODO</title> |
7 |
|
8 |
<link rel="stylesheet" href="css/reset.css" type="text/css" /> |
9 |
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" /> |
10 |
<link rel="stylesheet" href="css/flick/jquery-ui-1.8.16.custom.css" type="text/css" /> |
11 |
|
12 |
<script src="js/jquery.min.js"></script> |
13 |
<script src="js/jquery-ui-1.8.16.custom.min.js"></script> |
14 |
|
15 |
<style>
|
16 |
body { |
17 |
padding-top: 40px; |
18 |
}
|
19 |
#main { |
20 |
margin-top: 80px; |
21 |
}
|
22 |
|
23 |
.textalignright { |
24 |
text-align: right; |
25 |
}
|
26 |
|
27 |
.marginbottom10 { |
28 |
margin-bottom: 10px; |
29 |
}
|
30 |
#newtodo_window { |
31 |
text-align: left; |
32 |
display: none; |
33 |
}
|
34 |
</style>
|
35 |
|
36 |
<script>
|
37 |
$(document).ready(function() { |
38 |
$("#todolist").accordion({ |
39 |
collapsible: true |
40 |
});
|
41 |
$(".datepicker").datepicker(); |
42 |
$('#newtodo_window').dialog({ |
43 |
autoOpen: false, |
44 |
height: 'auto', |
45 |
width: 'auto', |
46 |
modal: true |
47 |
});
|
48 |
$('#newtodo').click(function() { |
49 |
$('#newtodo_window').dialog('open'); |
50 |
});
|
51 |
});
|
52 |
</script>
|
53 |
</head>
|
54 |
<body>
|
55 |
<div class="topbar"> |
56 |
<div class="fill"> |
57 |
<div class="container"> |
58 |
<a class="brand" href="index.php">SimpleTODO</a> |
59 |
</div>
|
60 |
</div>
|
61 |
</div>
|
62 |
<div id="main" class="container"> |
63 |
<div class="textalignright marginbottom10"> |
64 |
<span id="newtodo" class="btn info">Create a new TODO item</span> |
65 |
<div id="newtodo_window" title="Create a new TODO item"> |
66 |
<form method="POST" action="new_todo.php"> |
67 |
<p>Title:<br /><input type="text" class="title" name="title" placeholder="TODO title" /></p> |
68 |
<p>Date Due:<br /><input type="text" class="datepicker" name="due_date" placeholder="MM/DD/YYYY" /></p> |
69 |
<p>Description:<br /><textarea class="description" name="description"></textarea></p> |
70 |
<div class="actions"> |
71 |
<input type="submit" value="Create" name="new_submit" class="btn primary" /> |
72 |
</div>
|
73 |
</form>
|
74 |
</div>
|
75 |
</div>
|
76 |
<div id="todolist"> |
77 |
<?php foreach($todo_items as $todo): ?>
|
78 |
<h3><a href="#"><?php echo $todo->title; ?></a></h3> |
79 |
<div>
|
80 |
<form method="POST" action="update_todo.php"> |
81 |
<div class="textalignright"> |
82 |
<a href="delete_todo.php?todo_id=<?php echo $todo->todo_id; ?>">Delete</a> |
83 |
</div>
|
84 |
<div>
|
85 |
<p>Date Due:<br /><input type="text" id="datepicker_<?php echo $todo->todo_id; ?>" class="datepicker" name="due_date" value="12/09/2011" /></p> |
86 |
<p>Description:<br /><textarea class="span8" id="description_<?php echo $todo->todo_id; ?>" class="description" name="description"><?php echo $todo->description; ?></textarea></p> |
87 |
</div>
|
88 |
<div class="textalignright"> |
89 |
<?php if( $todo->is_done == 'false' ): ?>
|
90 |
<input type="hidden" value="false" name="is_done" /> |
91 |
<input type="submit" class="btn" value="Mark as Done?" name="markasdone_button" /> |
92 |
<?php else: ?>
|
93 |
<input type="hidden" value="true" name="is_done" /> |
94 |
<input type="button" class="btn success" value="Done!" name="done_button" /> |
95 |
<?php endif; ?>
|
96 |
<input type="hidden" value="<?php echo $todo->todo_id; ?>" name="todo_id" /> |
97 |
<input type="hidden" value="<?php echo $todo->title; ?>" name="title" /> |
98 |
<input type="submit" class="btn primary" value="Save Changes" name="update_button" /> |
99 |
</div>
|
100 |
</form>
|
101 |
</div>
|
102 |
<?php endforeach; ?>
|
103 |
</div>
|
104 |
</div>
|
105 |
</body>
|
106 |
</html>
|
Ahora debería verse como esto:


Genial, ¿eh? Pero esto actualmente no hace nada, así que comencemos a agregar algunas funcionalidades. Proporcionaré el código para new_todo.php, que llamará a todo/create para crear un nuevo elemento en el TODO. Crear las otras páginas (update_todo.php y delete_todo.php) debería ser muy similar a este, así que dejo que tú lo crees. Abre new_todo.php y agrega el siguiente código:
1 |
|
2 |
|
3 |
<?php
|
4 |
session_start(); |
5 |
include_once 'apicaller.php'; |
6 |
|
7 |
$apicaller = new ApiCaller('APP001', '28e336ac6c9423d946ba02d19c6a2632', 'http://localhost/simpletodo_api/'); |
8 |
|
9 |
$new_item = $apicaller->sendRequest(array( |
10 |
'controller' => 'todo', |
11 |
'action' => 'create', |
12 |
'title' => $_POST['title'], |
13 |
'due_date' => $_POST['due_date'], |
14 |
'description' => $_POST['description'], |
15 |
'username' => $_SESSION['username'], |
16 |
'userpass' => $_SESSION['userpass'] |
17 |
));
|
18 |
|
19 |
header('Location: todo.php'); |
20 |
exit(); |
21 |
?>
|
Como puedes ver, la página new_todo.php usa ApiCaller nuevamente para facilitar el envío de la solicitud todo/create al servidor API. Esto básicamente hace lo mismo que antes:
- iniciar una sesión para que tenga acceso al
$usernamey$userpassguardados en$_SESSION - instanciar una nueva clase
ApiCaller, dándole laAPP ID, laAPP KEYy la URL del servidor API - enviar la solicitud a través del método
sendRequest() - redirigir a
todo.php


Felicidades, ¡funciona! ¡Has creado con éxito una aplicación centrada en API!
Conclusión
Hay tantas ventajas para desarrollar una aplicación que se base en una API. ¿Deseas crear una versión Android de la aplicación SimpleTODO? Toda la funcionalidad que necesitarías ya está en el servidor API, ¡así que todo lo que necesitas hacer es crear el cliente! ¿Deseas refactorizar u optimizar algunas de las clases? No hay problema — solo asegúrate de que la salida sea la misma. ¿Necesitas agregar más funcionalidades? ¡Puedes hacerlo sin afectar el código del cliente!
Aunque hay algunas desventajas, como tiempos de desarrollo más largos o más complejidad, las ventajas de desarrollar una aplicación web de esta manera superan con creces las desventajas. Depende de nosotros aprovechar este tipo de desarrollo hoy para que podamos cosechar los beneficios más adelante.
¿Estás planeando usar un servidor API para tu próxima aplicación web o ya utilizaste la misma técnica para un proyecto en el pasado? ¡Házmelo saber en los comentarios!





