Post on 06-Jun-2015
description
Criando APIsusando o micro-framework
Silex
Elton MinettoGraduado/pós-graduado em Ciência da Computação
Desenvolvedor desde 1997Professor desde 2004
Autor de dois livros sobre PHP
Sócio da CoderockrInstrutor do Code Squad
API
O que é?
"[] conjunto de rotinas e padrões estabelecidos por um software para a utilização das suas funcionalidades por aplicativos que não pretendem envolver-se em detalhes da implementação do software, mas apenas usar seus serviços []"
Wikipedia
Porque criar uma API?
Múltiplas interfaces (web, mobile, CLI)
Integração com outros serviços da sua empresa
Venda de recursos (Amazon, Parse, Pusher, Filepicker, etc)
Exemplo
RestBeer
API de informações sobre cerveja
http://restbeer.com/cervejas/http://restbeer.com/estilos/
http://restbeer.com/cervejas/Guinnesshttp://restbeer.com/cervejas/Heineken
http://restbeer.com/estilos/Pilsenhttp://restbeer.com/estilos/Stout
Silex
Micro-framework para PHP 5.3 (e
superiores) construído com base nos componentes do Symfony e inspirado no Sinatra (ruby)
Instalando
Criando o composer.json{ "require": { "silex/silex": "1.0.*" }, "minimum-stability": "dev"}
Instalando as dependências
curl -s http://getcomposer.org/installer | phpphp composer.phar install
Mostrando as cervejas
<?phpuse Silex\Application;
//loader do Composer$loader = require_once __DIR__.'/vendor/autoload.php';
$app = new Application();
$cervejas = array( 'marcas' => array('Heineken', 'Guinness', 'Skol', 'Colorado'), 'estilos' => array('Pilsen' , 'Stout'));
$app->get('/cervejas', function () use ($cervejas) { return implode(',', $cervejas['marcas']);});
$app->get('/estilos', function () use ($cervejas) { return implode(',', $cervejas['estilos']);});$app->run();
Testando com o servidor do PHP 5.4
php -S localhost:8080
Mostrando uma em específico
$app->get('/cervejas/{id}', function ($id) use ($cervejas) { if ($id == null) { return implode(',', $cervejas['marcas']); } $key = array_search($id, $cervejas['marcas']); if ($key === null) { return 'Não encontrada'; } return $cervejas['marcas'][$key];})->value('id', null);
Formatando o resultado
//Adicionar os novos namespaces no começo do arquivouse Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpFoundation\Request;...//alterar o /cervejas$app->get('/cervejas/{id}', function ($id) use ($cervejas) { if ($id == null) { $result = implode(',', $cervejas['marcas']); return new Response (json_encode($result), 200); } $key = array_search($id, $cervejas['marcas']); if ($key === null) { return new Response (json_encode('Não encontrada'), 404); } return new Response (json_encode($cervejas['marcas'][$key]), 200); })->value('id', null);
//adiciona o cabeçalho após todas as requisições$app->after(function (Request $request, Response $response) { $response->headers->set('Content-Type', 'text/json');});
Autenticando
$app->before(function (Request $request) use ($app) { if( ! $request->headers->has('authorization')){ return new Response('Unauthorized', 401); }
require_once 'configs/clients.php'; if (!in_array($request->headers->get('authorization'), array_keys($clients))) { return new Response('Unauthorized', 401); }});
Adicionando uma Cerveja
$app->post('/cervejas', function (Request $request) use ($app) { //pega os dados if (!$data = $request->get('cerveja')) { return new Response('Faltam parâmetros', 400); }
//Persiste na base de dados (considerando uma entidade do Doctrine nesse exemplo) $cerveja = new Cerveja(); $cerveja->nome = $data['nome']; $cerveja->estilo = $data['estilo']; $cerveja->save(); //redireciona para a nova cerveja return $app->redirect('/cervejas/' . $data['nome'], 201);});
Alterando uma Cerveja
$app->put('/cervejas/{id}', function (Request $request, $id) use ($app) { //pega os dados if (!$data = $request->get('cerveja')) { return new Response('Faltam parâmetros', 400); } //busca da base de dados if (!$cerveja = $app['db']->find($id)) { return new Response('Não encontrada', 404); } //Persiste na base de dados $cerveja->nome = $data['nome']; $cerveja->estilo = $data['estilo']; $cerveja->save(); return new Response('Cerveja atualizada', 200);});
Excluindo uma Cerveja
$app->delete('/cervejas/{id}', function (Request $request, $id) use ($app) { //busca da base de dados if (!$cerveja = $app['db']->find($id)) { return new Response('Não encontrada', 404); } $cerveja->delete(); return new Response('Cerveja removida', 200);});
Referências
Exemplo completo (com integração com o Docrine e usando SQLite)
https://github.com/eminetto/restbeer
http://www.slideshare.net/hhamon/silex-meets-soap-resthttp://www.slideshare.net/Alganet/rest-faa-o-servio-direitohttp://silex.sensiolabs.orghttps://github.com/eminetto/silex-samplehttps://github.com/Coderockr/SOA-Serverhttps://github.com/Coderockr/SOA-Client
Contato
@eminettohttp://www.eltonminetto.net
http://coderockr.comhttp://code-squad.com