Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rest Beer v2

Rest Beer v2

Criando APIs com micro framework RESPECT e Jelastic Locaweb

Avatar for Ivan Rosolen

Ivan Rosolen

October 04, 2015
Tweet

More Decks by Ivan Rosolen

Other Decks in Technology

Transcript

  1. Ivan Rosolen Graduado em Sistemas de Informação Pós-graduado em Gerência

    de Projetos Desenvolvedor a 14+ anos Autor de vários PHPT (testes para o PHP) Entusiasta de novas tecnologias Head of Innovation @ Arizona CTO @ Mokation
  2. API

  3. Vantagens - Troca de informações entre sistemas - Múltiplas interfaces

    (web, mobile, CLI) - Módulos/Componentes - HTTP Status Codes - Controle de Acesso https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
  4. API com informações de Ceveja! GET - http://hostname/cerveja/ POST -

    http://hostname/cerveja/ cerveja[nome] cerveja[estilo] PUT - http://hostname/cerveja/NOME cerveja[nome] cerveja[estilo] DELETE - http://hostname/cerveja/NOME
  5. { "name": "RestBeer Jelastic Demo", "authors": [ { "name": "Ivan

    Rosolen", "email": "[email protected]" } ], "require": { "respect/rest": "0.5.x", "respect/relational": "0.5.x", "respect/config": "0.3.x", "respect/validation": "0.4.x" } }
  6. Respect/Config - Apenas arquivos .INI - Usa o mesmo parser

    nativo e rápido do php.ini - Extende o arquivo .INI com seu próprio “dialeto” - Implementa lazy loading para instâncias de objeto https://github.com/Respect/Config
  7. db_server = "127.0.0.1" db_name = "restbeer" db_user = "user" db_pwd

    = "pwd" dsn_mysql = "mysql:host=[db_server];dbname=[db_name]" <?php use Respect\Config\Container; // Ler arquivo de configuração $config = new Container('config.ini'); echo $config->dsn_mysql; // mysql:host=127.0.0.1;dbname=restbeer
  8. Respect/Relational - Quase zero de configuracão (convenção) - Fluent interface:

    $mapper->author[7]->fetch(); - Diferentes tipos de banco de dados - Registros são tratados como Plain Data Object https://github.com/Respect/Relational
  9. <?php use Respect\Relational\Mapper; // criar instância PDO com o banco

    $mapper = new Mapper(new PDO('seudsn')); // buscar todos os autores $authors = $mapper->author->fetchAll(); // criar objeto de um registro $obj = new stdClass; $obj->name = 'Ivan Rosolen'; // "gravar" informação no banco $mapper->author->persist($obj); $mapper->flush();
  10. Respect/Validation - Fluent/Chained interface: v::numeric()->positive()->between(1, 256)->validate($num) - 100+ validadores testados

    - Fácil extender ou criar novas regras (Concrete API) - Php 7 ( Quase pronto ) https://github.com/Respect/Validation
  11. use Respect\Validation\Validator as v; // validar número simples v::numeric()->validate(42); //true

    // validar em cadeia $v = v::arr() // validar se é array ->key('nome', $rule = v::alnum()->notEmpty()->noWhitespace()) // validar a key 'nome' ->key('estilo', $rule) // utilizando a mesma regra da key de cima ->validate($_POST['cerveja']); // negação de qualquer regra $v = v::not(v::int())->validate(10); // false // operadores lógicos v::allOf(v::numeric(), v::hexa(), v::min(1)); // numeric, hexadecimal e pelo menos 1 v::oneOf(v::nullValue(), v::numeric()); // null ou numeric
  12. Respect/Router - Thin and lightweight controller para aplicações RESTful e

    APIs - “Don't try to change PHP, small learning curve.” - If/Before/After/Accept/Auth/Any/By … https://github.com/Respect/Rest
  13. <?php use Respect\Rest\Router; // Criar instância do router $router =

    new Router; // raiz http://example.com/ // instância para trabalhar em uma subpasta $router = new Router('/pasta'); // raiz http://example.com/pasta // Olá mundo $router->get('/', function() { return 'Hello World'; }); // Separando regras das rotas :D $router->get('/api/uri/*/*', 'Namespace\Cool\Class'); $router->post('/api/uri/', 'Namespace\Cool\Class'); $router->put('/api/uri/', 'Namespace\Cool\Class'); $router->delete('/api/uri/*', 'Namespace\Cool\Class');
  14. <?php require_once realpath(__DIR__ . '/vendor/autoload.php'); use Respect\Rest\Router; use Respect\Config\Container; use

    Respect\Validation\Validator as v; use Respect\Relational\Mapper; //Ler arquivo de configuração $config = new Container('config.ini'); // Criar instância PDO com o SQLite usando as configs $mapper = new Mapper(new PDO($config->dsn_sqlite)); // Criar instância do router $router = new Router(); //Rota para qualquer tipo de request (any) $router->any('/', function () { return 'RestBeer!'; });
  15. $router->get('/cerveja/*', function ($data = null) use ($mapper) { if (

    !isset($data) ) { $cervejas = $mapper->cervejas->fetchAll(); header('HTTP/1.1 200 Ok'); return $cervejas; } $data = filter_var( $data, FILTER_SANITIZE_FULL_SPECIAL_CHARS ); if ( v::not(v::alnum()->notEmpty())->validate($data) ) { header('HTTP/1.1 400 Bad Request'); return 'Faltam parâmetros'; } $cerveja = $mapper->cervejas(array( 'nome' => $data ))->fetch(); if ( !$cerveja ) { header('HTTP/1.1 204 No Content'); return; } header('HTTP/1.1 200 Ok'); return $cerveja; });
  16. $router->post('/cerveja', function () use ($mapper) { if ( !isset($_POST) ||

    !isset($_POST['cerveja']) || v::not(v::arr())->validate($_POST['cerveja']) ) { header('HTTP/1.1 400 Bad Request'); return 'Faltam parâmetros'; } $valid = v::arr()->key('nome', $rule = v::alnum()->noWhitespace())->key('estilo', $rule)->validate($_POST['cerveja']); if ( !$valid ) { header('HTTP/1.1 400 Bad Request'); return 'Faltam parâmetros'; } $cerveja = new stdClass(); $cerveja->nome = filter_var($_POST['cerveja']['nome'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); $cerveja->estilo = filter_var($_POST['cerveja']['estilo'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); $check = $mapper->cervejas(array( 'nome' => $cerveja->nome ))->fetch(); if ( $check ) { header('HTTP/1.1 409 Conflict'); return 'Cerveja já existe no sistema'; } $mapper->cervejas->persist($cerveja); $mapper->flush(); if ( !isset($cerveja->id) || empty($cerveja->id) ) { header('HTTP/1.1 422 Unprocessable Entity'); return 'Erro ao inserir cerveja'; } header('HTTP/1.1 201 Created'); return 'Cerveja criada'; });
  17. $router->put('/cerveja/*', function ($nome) use ($mapper) { parse_str(file_get_contents('php://input'), $data); if (

    !isset($data) || !isset($data['cerveja']) || v::not(v::arr())->validate($data['cerveja']) ) { header('HTTP/1.1 400 Bad Request'); return 'Faltam parâmetros'; } $nome = filter_var( $nome, FILTER_SANITIZE_FULL_SPECIAL_CHARS ); if ( v::not(v::alnum()->notEmpty())->validate($nome) ) { header('HTTP/1.1 400 Bad Request'); return 'Faltam parâmetros'; } $cerveja = $mapper->cervejas(array( 'nome' => $nome ))->fetch(); if ( !$cerveja ) { header('HTTP/1.1 204 No Content'); return; } $newNome = filter_var( $data['cerveja']['nome'], FILTER_SANITIZE_FULL_SPECIAL_CHARS ); $newEstilo = filter_var( $data['cerveja']['estilo'], FILTER_SANITIZE_FULL_SPECIAL_CHARS ); $cerveja->nome = $newNome; $cerveja->estilo = $newEstilo; $mapper->cervejas->persist($cerveja); $mapper->flush(); header('HTTP/1.1 200 Ok'); return 'Cerveja atualizada'; }); * removido parte do código para ficar melhor no slide
  18. $router->delete('/cerveja/*', function ($nome) use ($mapper) { $nome = filter_var( $nome,

    FILTER_SANITIZE_FULL_SPECIAL_CHARS ); if ( !isset($nome) || v::not(v::alnum()->notEmpty())->validate($nome) ) { header('HTTP/1.1 400 Bad Request'); return 'Faltam parâmetros'; } $cerveja = $mapper->cervejas(array( 'nome' => $nome ))->fetch(); if ( !$cerveja ) { header('HTTP/1.1 422 Unprocessable Entity'); return 'Erro ao validar cerveja'; } $mapper->cervejas->remove($cerveja); $mapper->flush(); header('HTTP/1.1 200 Ok'); return 'Cerveja removida'; });
  19. <?php $jsonRender = function ($data) { header('Content-Type: application/json'); if (

    v::string()->validate($data) ) { $data = array($data); } return json_encode($data,true); }; $router->always('Accept', array('application/json' => $jsonRender));
  20. <?php // do not use this! function checkLogin($user, $pass) {

    return $user === 'admin' && $pass === 'admin'; } $router->get('/admin', function () { return 'RestBeer Admin Protected!'; })->authBasic('Secret Area', function ($user, $pass) { return checkLogin($user, $pass); });
  21. Jelastic - Locaweb? - Git - Barato - 14 Dias

    Grátis Aplicações PHP no Jelastic https://t.co/aHi3ZixLon