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

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