API RESTful com PHP e Slim Framework

Olá pessoal, hoje veremos um exemplo de como utilizar o Slim Framework para construir uma API RESTful com PHP.

O que é RESTful

REST é a abreviação de Representation State Transfer, ou traduzindo, Transferência de Estado Representacional. Tal arquitetura tem como base três princípios: Recursos, ações e conteúdo.

Recursos

Estes são identificados na requisição, por exemplo: http://api.clubedosgeeks.com.br/usuario/jayr

Ações

São as ações definidas pelo protocolo HTTP:

Metodo Exemplo Descrição
GET //api.clubedosgeeks.com.br/usuarios Lista todos os usuários
GET //api.clubedosgeeks.com.br/usuario/1 Lista apenas usuário com id = 1
POST //api.clubedosgeeks.com.br/usuarios Para cadastrar usuários
PUT //api.clubedosgeeks.com.br/usuario/1 Para editar usuários
DELETE //api.clubedosgeeks.com.br/usuario/1 Para apagar usuário

Conteúdo

MIME TYPES – Deve ser usado para determinar o tipo de conteúdo que será usado. A identificação geralmente é feita no cabeçalho pelo campo cujo o nome é Content-type. Normalmente os tipos usados são JSON e XML. No nosso exemplo usaremos JSON.

Banco de dados

Iremos usar o mysql, crie um banco de dados, e uma tabela simples para cadastro de pessoa.

CREATE DATABASE api;
CREATE TABLE pessoa (
	id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
	nome VARCHAR(30) NOT NULL,
	email VARCHAR(50),
	dt_cadastro DATETIME DEFAULT CURRENT_TIMESTAMP
)

Slim Framework

É considerado um microframework, e tem como principal objetivo a construção de APIs. Veja o site oficial.

Instalando

Para instalar o Slim você vai precisar usar composer. Instale-o primeiro.

Crie um arquivo chamado composer.json, e escreva o seguinte nele:

{
	"require": {
		"slim/slim": "2.*"
	},
	"autoload": {
		"psr-4": {
			"controllers\\": "controllers"
		}
	}
}

Feito isso, abra o terminal ou o Prompt de comando, vá até a pasta de sua aplicação usando cd, e execute:

$ composer install

Pronto, está instalado! Agora vamos começar nossa aplicação.

Antes, note que no composer colocamos a pasta controllers para ser inclusa na nossa aplicação via autoloader.

.htaccess

Para começar, acesse a pasta \vendor\slim\slim, e copie o arquivo .htaccess para a pasta raiz da sua aplicação.

Estrutura das pastas

Nossa API será organizada da seguinte maneira:

ac.fw

templates/default.php

Este arquivo, como o nome sugere, é um arquivo padrão de template, que nos servirá como view. Este arquivo deve setar os cabeçalhos e mostrar o json.

<?php 
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);

controllers/Pessoa.php

Neste arquivo faremos os controles das ações, listando, salvando, editando e excluindo.

Note que usei a biblioteca PDO, e em alguns pontos você pode achar que tem muito código escrito, como na função editar por exemplo. Mas você pode usar a conexão que quiser. Gosto do PDO por ser orientado a objetos. Mas fica ao seu dispor.

<?php
namespace controllers{
	/*
	Classe pessoa
	*/
	class Pessoa{
		//Atributo para banco de dados
		private $PDO;

		/*
		__construct
		Conectando ao banco de dados
		*/
		function __construct(){
			$this->PDO = new \PDO('mysql:host=localhost;dbname=api', 'root', ''); //Conexão
			$this->PDO->setAttribute( \PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION ); //habilitando erros do PDO
		}
		/*
		lista
		Listand pessoas
		*/
		public function lista(){
			global $app;
			$sth = $this->PDO->prepare("SELECT * FROM pessoa");
			$sth->execute();
			$result = $sth->fetchAll(\PDO::FETCH_ASSOC);
			$app->render('default.php',["data"=>$result],200); 
		}
		/*
		get
		param $id
		Pega pessoa pelo id
		*/
		public function get($id){
			global $app;
			$sth = $this->PDO->prepare("SELECT * FROM pessoa WHERE id = :id");
			$sth ->bindValue(':id',$id);
			$sth->execute();
			$result = $sth->fetch(\PDO::FETCH_ASSOC);
			$app->render('default.php',["data"=>$result],200); 
		}

		/*
		nova
		Cadastra pessoa
		*/
		public function nova(){
			global $app;
			$dados = json_decode($app->request->getBody(), true);
			$dados = (sizeof($dados)==0)? $_POST : $dados;
			$keys = array_keys($dados); //Paga as chaves do array
			/*
			O uso de prepare e bindValue é importante para se evitar SQL Injection
			*/
			$sth = $this->PDO->prepare("INSERT INTO pessoa (".implode(',', $keys).") VALUES (:".implode(",:", $keys).")");
			foreach ($dados as $key => $value) {
				$sth ->bindValue(':'.$key,$value);
			}
			$sth->execute();
			//Retorna o id inserido
			$app->render('default.php',["data"=>['id'=>$this->PDO->lastInsertId()]],200); 
		}

		/*
		editar
		param $id
		Editando pessoa
		*/
		public function editar($id){
			global $app;
			$dados = json_decode($app->request->getBody(), true);
			$dados = (sizeof($dados)==0)? $_POST : $dados;
			$sets = [];
			foreach ($dados as $key => $VALUES) {
				$sets[] = $key." = :".$key;
			}

			$sth = $this->PDO->prepare("UPDATE pessoa SET ".implode(',', $sets)." WHERE id = :id");
			$sth ->bindValue(':id',$id);
			foreach ($dados as $key => $value) {
				$sth ->bindValue(':'.$key,$value);
			}
			//Retorna status da edição
			$app->render('default.php',["data"=>['status'=>$sth->execute()==1]],200); 
		}

		/*
		excluir
		param $id
		Excluindo pessoa
		*/
		public function excluir($id){
			global $app;
			$sth = $this->PDO->prepare("DELETE FROM pessoa WHERE id = :id");
			$sth ->bindValue(':id',$id);
			$app->render('default.php',["data"=>['status'=>$sth->execute()==1]],200); 
		}
	}
}

index.php

Na pasta raiz da aplicação teremos um arquivo chamado index.php que será o arquivo principal da aplicação.

Nele faremos nossas rotas para o(s) controller(s). Se você preferir ter um arquivo de rotas separado, basta incluir ele depois.

<?php
//Autoload
$loader = require 'vendor/autoload.php';

//Instanciando objeto
$app = new \Slim\Slim(array(
    'templates.path' => 'templates'
));

//Listando todas
$app->get('/pessoas/', function() use ($app){
	(new \controllers\Pessoa($app))->lista();
});

//get pessoa
$app->get('/pessoas/:id', function($id) use ($app){
	(new \controllers\Pessoa($app))->get($id);
});

//nova pessoa
$app->post('/pessoas/', function() use ($app){
	(new \controllers\Pessoa($app))->nova();
});

//edita pessoa
$app->put('/pessoas/:id', function($id) use ($app){
	(new \controllers\Pessoa($app))->editar($id);
});

//apaga pessoa
$app->delete('/pessoas/:id', function($id) use ($app){
	(new \controllers\Pessoa($app))->excluir($id);
});

//Rodando aplicação
$app->run();

Pronto está pronta nossa API.

Testando

Você pode testar sua nova API usando Postman, ou outro cliente REST.

GitHub

Você pode ver este projeto no GitHub

 

Jayr Alencar

Doutorando em Ciências da Computação no Centro de Informática da Universidade Federal do Pernambuco (CIn - UFPE); Mestre pela mesma instituição; Formado em Análise e Desenvolvimento de Sistemas; Católico; Fã de O Senhor do Anéis.

Você pode gostar...

23 Resultados

  1. jose soares disse:

    Muito bom… Parabens pelo artigo.
    todos os comandos funcionaram menos o editar (put).
    talvez seje porque usando no windows.

  2. Tarcio Rodrigo Almeida dos Santos disse:

    como ficaria esse exemplo com autenticação?

  3. Djalma Manfrin disse:

    Gostaria de fazer uma pergunta. Se tratando de uma API grande. Os cadastros, as alterações e as exclusões não são feitas em blocos? Como funcionaria essa parte se eu tivesse um array de objetos para realizar essas operações?

  4. Diego disse:

    Muito útil esse tutorial!

    Fiquei apenas com uma dúvida, no caso da consulta, teria como passar dois parâmetos ao invés de mandar somente o ID ?

  5. Marcio Souza disse:

    Parabéns pelo seu trabalho, consegui usá-lo e a sua abordagem é bem legal. Vi que a versão da Slim é 2.6 para este exemplo, teria como você atualizar para 3.0, pois teve muitos métodos que mudaram ?

  6. Ryan Felipe disse:

    Parabéns brother, muito bem explicado. Me ajudou bastante aqui 🙂

  7. Matheus disse:

    Parabéns pelo seu trabalho ficou muito bom e fácil de entender. Preciso fazer um trabalho na faculdade usando a linguagem php, como sou iniciante não estou conseguido configurar o CORS. Pode me ajudar ?

  8. Adriano disse:

    Boa noite, era o que eu precisava.
    Sou novo em php, para colocar isto nas nuvens, o processo e igual ao colocar uma pagina ou tem algum segredinho a mais?
    Obrigado

  9. João Henrique de oliveira disse:

    Muito bom e muito util, mas fiquei na duvida de como eu passaria um filtro na função lista(), para obter os dados filtrados

  10. Miquéias disse:

    Boa tarde,
    como faço para retornar os códigos de resposta http (ex. 200, 401)?

  11. Ismael do Vale disse:

    Tem como atualizar para Slim 3?

  12. Patrick disse:

    Acredito que seja apenas necessário vc concatenar com sua Consulta SQL

  13. Marcelo disse:

    Tentei fazer mas nao deu certo, fiz ate um git clone também não funcionou deu 404,
    http://localhost/api-php-slim-framework/pessoas/. Alguém poderia me ajudar aonde estou errando.

  14. Anderson disse:

    Olá.

    Excelente o seu post. Testei aqui e funcionou perfeitamente.

    A minha dúvida é:

    Eu poderia passar o nome do controller dinamicamente?

    $app->post(‘/pessoas/’, function() use ($app){
    (new \controllers\Pessoa($app))->nova();
    });

    no caso, passar dinamicamente o ‘/pessoas/’ eu consigo, mas o \controllers\Pessoa eu não consegui fazer.

    tem uma dica?

  15. Paulo Henrique disse:

    Não estou conseguindo testar, poderia me auxiliar, grato

  1. 24 de junho de 2016

    […] Existem vários outros frameworks para construir APIs com PHP, um deles é o Slim Framework, que é na verdade um micro-framework, e é bem mais simples que o Laravel. Veja como construir uma API RESTful com PHP e Slim Framework. […]

Deixe um comentário para Jayr Alencar Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *