2012-01-18 11 views
10

Estoy buscando crear un sitio web y crearé una aplicación móvil en una fecha posterior.Zend Framework: ¿cómo crear una API a la que se pueda acceder tanto externa como internamente?

Quiero poder ofrecer el mismo nivel de datos (es decir, una lista de libros) tanto para el sitio web como para la aplicación. Me gustaría utilizar una API para esto, pero estoy luchando para encontrar ejemplos o artículos decentes en línea.

Supongo que mi pregunta es, si tuviera que crear un 'punto final' JSON accesible mediante una aplicación móvil a través de HTTP (por ejemplo, http://www.mysite.com/api/v1.0/json) ¿cómo acceder a la misma funcionalidad internamente desde mi aplicación Zend?

(obviamente, no quieren duplicar la base de datos de interacción pasos 'modelo')

+0

¿Qué le terminan usando aquí? Estoy en una situación similar en este momento. –

Respuesta

4

Desde Zend es realmente no REST, por desgracia, su mejor apuesta es JSON-RPC.

Puede hacerlo en un controlador, o puede simplemente hacer una ajax.php, además de su index.php para reducir la sobrecarga como este tipo hizo here

Básicamente, todo lo que tiene que hacer es la siguiente:

$server = new Zend_Json_Server(); 
$server->setClass('My_Class_With_Public_Methods'); 
// I've found that a lot of clients only support 2.0 
$server->getRequest()->setVersion("2.0"); 
if ('GET' == $_SERVER['REQUEST_METHOD']) { 
    // Indicate the URL endpoint, and the JSON-RPC version used: 
    $server->setTarget('/ajax.php') 
      ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2); 

    // Grab the SMD 
    $smd = $server->getServiceMap(); 

    // Return the SMD to the client 
    header('Content-Type: application/json'); 
    echo $smd; 
    return; 
} 

$server->handle(); 

continuación, en algún lugar de su diseño:

$server = new Zend_Json_Server(); 
$server->setClass('My_Class_With_Public_Methods'); 
$smd = $server->getServiceMap(); 
?> 
<script> 
$(document).ready(function() { 
    rpc = jQuery.Zend.jsonrpc({ 
     url : <?=json_encode($this->baseUrl('/ajax'))?> 
     , smd : <?=$smd?> 
     , async : true 
    }); 
}); 
</script> 

por el bien de ejemplo, aquí está esa clase:

class My_Class_With_Public_Methods { 
    /** 
     * Be sure to properly phpdoc your methods, 
     * the rpc clients like it when you do 
     * 
     * @param float $param1 
     * @param float $param2 
     * @return float 
     */ 
    public function someMethodInThatClass ($param1, $param2) { 
     return $param1 + $param2; 
    } 
} 

, entonces puede simplemente llamar a métodos como tal en javascript:

rpc.someMethodInThatClass(first_param, second_param, { 
    // if async = true when you setup rpc, 
    // then the last param is an object w/ callbacks 
    'success' : function(data) { 

    } 
    'error' : function(data) { 

    } 
}); 

no hay una gran cantidad de bibliotecas JSON-RPC bien conocidos para Android/iPhone - pero he encontrado que esto funciona con Zend_Json_Server para Android:

http://software.dzhuvinov.com/json-rpc-2.0-base.html

y esto funciona para iPhone:

http://www.dizzey.com/development/ios/calling-json-rpc-webservice-in-ios/

Desde aquí, obviamente, puede usar My_Class_With_Public_Methods de la misma forma que lo hace javascript/su aplicación móvil.

+0

¿Cómo podría llamar al método someMethodInThatClass desde la acción 'index' del controlador 'books', por ejemplo? – Sjwdavies

+1

heh, llamándolo? '$ myobj = new My_Class_With_Public_Methods(); $ myobj-> someMethodInThatClass(); ' –

+0

Gracias Stephen - ¿No terminaría con el 'Fat Controller', por ej. 'My_Class_With_Public_Methods' podría ser masivo? ¿Estaba pensando que necesitaría dirigir todas las solicitudes internas a la base de datos para datos a través de este controlador? ¿O los dirijo de la manera normal, luego "abro" el proceso de recuperación de datos escribiendo el archivo "My_Class_With_Public_Methods" y selecciono las interacciones de la base de datos que deseo ofrecer "públicamente"? – Sjwdavies

1

Desde mi punto de vista, esta es más una pregunta relacionada con la arquitectura que una pregunta de Zend Framework.

Lo que está buscando es Arquitectura orientada a servicios (SOA).

La premisa detrás de SOA es simple, compilar una única API y hacer que todo pase por ella, ya sea interna o externamente. Un defensor popular de SOA es Amazon.

En la práctica, significa que expone su API exactamente como la usaría internamente. En OOP, esto significa que siempre que llame a su API desde una fuente externa (por ejemplo: una API REST), especificará un nombre de clase, un nombre de método y una lista de argumentos, y recibirá un objeto a cambio, como lo haría si lo llamara internamente.

Por ejemplo, usted tiene los siguientes:

class HelloInstance { 
    public $hello; 
    public function __construct($hello) { $this->hello = $hello; } 
} 

class Hello { 
    public function getHello() { return new HelloInstance('world'); } 
} 

class FooInstance { 
    public $foo; 
    public function __construct($foo) { $this->foo = $foo; } 
} 

class Foo { 
    public function getFoo($value) { return new FooInstance($value); } 
} 

Si desea utilizar internamente, que harían:

$hello = new Hello; 
$helloInst = $hello->getHello(); 

$foo = new Foo; 
$fooInst = $foo->getFoo('bar'); 

Ahora sólo tiene una puerta de entrada para exponer esta API externa. Aquí hay un ejemplo muy básico:

include_once 'my_classes.php'; 

$class = $_GET['class']; 
$method = $_GET['method']; 

$obj = new $class; 
$return = $obj->$method(isset($_GET['value']) ? $_GET['value'] : null); 

header('Content-Type: application/json'); 
echo json_encode($return); 

Puede hacer las mismas dos llamadas he demostrado antes, y obtener los mismos resultados, mediante una llamada REST:

http://my_server/my_gateway.php?class=Hello&method=getHello 
http://my_server/my_gateway.php?class=Foo&method=getFoo&value=bar 
+1

Esta es una buena respuesta de un arquitecto punto de vista, pero 1. lo que usted describe como REST no es realmente RESTful, es más parecido a SOAP. SOAP está bien y es bueno, pero decididamente * no * RESTful, y 2. Zend tiene SOA integrado, su servidor REST es una porquería y no es RESTful, pero su funcionalidad JSON/XML RPC está en lo cierto. Su enfoque está bien, por supuesto, pero no aprovecha ninguna de las SOA internas de Zend. Eso no es necesariamente algo malo, supongo, pero pensé que lo señalaría. –

+0

Simplemente curioso, ¿cómo no es RESTful? – drew010

+0

@ StephenJ.Fuhry: El hecho de que realice llamadas a procedimientos remotos no significa que no pueda ser RESTful. Ah, y nunca dije que lo anterior fuera RESTful por cierto. Y eso no es como SOAP en absoluto. – netcoder

Cuestiones relacionadas