rest beer v2
TRANSCRIPT
Ivan RosolenGraduado em Sistemas de InformaçãoPós-graduado em Gerência de Projetos
Desenvolvedor a 14+ anosAutor de vários PHPT (testes para o PHP)
Entusiasta de novas tecnologias
Head of Innovation @ Arizona
CTO @ Mokation
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
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
Composer
- Controle de dependências
curl -s http://getcomposer.org/installer | phpphp composer.phar install
https://getcomposer.org
{
"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"
}
}
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
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
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
<?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();
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
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
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
<?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');
<?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!';
});
$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;
});
$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';});
$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
$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';
});
<?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));
<?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);
});
Jelastic
- Locaweb?- Git- Barato- 14 Dias Grátis
Aplicações PHP no Jelastic https://t.co/aHi3ZixLon
Githubhttps://github.com/ivanrosolen/RestBeer-Jelastic
Respecthttp://respect.github.io
Jelastichttp://www.locaweb.com.br/cloud/jelastichttps://twitter.com/kemelzaidanhttp://pt.slideshare.net/ivanrosolen/jelastic-53375753
PHPSPhttp://phpsp.org.br
Elton Minettohttps://github.com/eminetto/restbeer
OBRIGADO!
Avalie esta palestrajoind.in/15207
Visite phpsp.org.br