Este pacote auxiliar fornece funcionalidade para analisar a URL de uma solicitação REST-API.
Nota: Esta versão é para Laravel 5. Ao usar o Laravel 4 você precisa usar a versão 0.4.x.
Instale o pacote através do compositor executando
composer require marcelgwerder/laravel-api-handler
Assim que o compositor terminar, adicione o provedor de serviços à matriz providers
em app/config/app.php
:
MarcelgwerderApiHandlerApiHandlerServiceProvider::class,
Agora importe a fachada ApiHandler
para suas classes:
use Marcelgwerder ApiHandler Facades ApiHandler ;
Ou defina um alias em app.php
:
'ApiHandler' => MarcelgwerderApiHandlerFacadesApiHandler::class,
É isso!
Os métodos de relação agora precisam de uma anotação @Relation
para provar que são métodos de relação e não quaisquer outros métodos (consulte a questão nº 11).
/**
* @Relation
*/
public function author () {
return $ this -> belongsTo ( ' Author ' );
}
Se você passar um array como segundo parâmetro para parseSingle
, agora deverá haver pares coluna/valor. Isso nos permite passar várias condições como:
ApiHandler :: parseSingle ( $ books , array ( ' id_origin ' => ' Random Bookstore Ltd ' , ' id ' => 1337 ));
Para substituir a configuração, crie um arquivo chamado apihandler.php
na pasta de configuração do seu aplicativo.
Confira o arquivo de configuração na fonte do pacote para ver quais opções estão disponíveis.
A análise de URL atualmente suporta:
Existem dois tipos de recursos de API suportados, um único objeto e uma coleção de objetos.
Se você lidar com uma solicitação GET em um recurso que representa um único objeto como, por exemplo, /api/books/1
, use o método parseSingle
.
parseSingle($queryBuilder, $identificação, [$queryParams]):
id
ou um(s) par(es) de coluna/valor da matriz ( array('isbn' => '1234')
) usado como um identificador exclusivo do objeto. ApiHandler :: parseSingle ( $ book , 1 );
Se você lidar com uma solicitação GET em um recurso que representa vários objetos, como por exemplo /api/books
, use o método parseMultiple
.
parseMultiple($queryBuilder, $fullTextSearchColumns, [$queryParams]):
ApiHandler :: parseMultiple ( $ book , array ( ' title ' , ' isbn ' , ' description ' ));
Tanto parseSingle
quanto parseMultiple
retornam um objeto Result
com os seguintes métodos disponíveis:
getBuilder(): Retorna o $queryBuilder
original com todas as funções aplicadas a ele.
getResult(): Retorna o objeto de resultado retornado pelas funções get()
ou first()
do Laravel.
getResultOrFail(): Retorna o objeto de resultado retornado pela função get()
do Laravel se você espera vários objetos ou firstOrFail()
se você espera um único objeto.
getResponse($resultOrFail = false): Retorna um objeto Laravel Response
incluindo corpo, cabeçalhos e código de status HTTP. Se $resultOrFail
for verdadeiro, o método getResultOrFail()
será usado internamente em vez de getResult()
.
getHeaders(): Retorna um array de cabeçalhos preparados.
getMetaProviders(): Retorna uma matriz de objetos meta-provedores. Cada um desses objetos fornece um tipo específico de metadados por meio de seu método get()
.
cleanup($cleanup): Se verdadeiro, o array resultante será limpo de relações adicionadas involuntariamente. Essas relações podem ser adicionadas automaticamente se forem acessadas como propriedades em acessadores de modelo. O padrão global para a limpeza pode ser definido usando a opção de configuração cleanup_relations
cujo padrão é false
.
ApiHandler :: parseSingle ( $ books , 42 )-> cleanup ( true )-> getResponse ();
Cada parâmetro de consulta, exceto as funções predefinidas _fields
, _with
, _sort
, _limit
, _offset
, _config
e _q
, é interpretado como um filtro. Certifique-se de remover parâmetros adicionais não destinados à filtragem antes de passá-los para parseMultiple
.
/api/books?title=The Lord of the Rings
Todos os filtros são combinados com um operador AND
.
/api/books?title-lk=The Lord*&created_at-min=2014-03-14 12:55:02
O exemplo acima resultaria no seguinte SQL onde:
WHERE ` title ` LIKE " The Lord% " AND ` created_at ` >= " 2014-03-14 12:55:02 "
Também é possível usar vários valores para um filtro. Vários valores são separados por uma barra vertical |
. Vários valores são combinados com OR
exceto quando há um sufixo -not
, então eles são combinados com AND
. Por exemplo todos os livros com id 5 ou 6:
/api/books?id=5|6
Ou todos os livros, exceto aqueles com id 5 ou 6:
/api/books?id-not=5|6
O mesmo poderia ser conseguido usando o sufixo -in
:
/api/books?id-in=5,6
Respectivamente o sufixo not-in
:
/api/books?id-not-in=5,6
Sufixo | Operador | Significado |
---|---|---|
-lk | COMO | Igual ao operador SQL LIKE |
-não-lk | NÃO GOSTO | Igual ao operador SQL NOT LIKE |
-em | EM | Igual ao operador SQL IN |
-não-dentro | NÃO ESTÁ EM | Igual ao operador SQL NOT IN |
-min | >= | Maior ou igual a |
-máx. | <= | Menor ou igual a |
-st | < | Menor que |
-gt | > | Maior que |
-não | != | Não é igual a |
Duas formas de classificação, ascendente e descendente. Cada coluna que deve ser classificada em ordem decrescente sempre começa com -
.
/api/books?_sort=-title,created_at
São suportadas duas implementações de pesquisa de texto completo. Você pode escolher qual usar alterando a opção fulltext
no arquivo de configuração para default
ou native
.
Nota: Ao usar um parâmetro _q
vazio, a pesquisa sempre retornará um resultado vazio.
Implementação personalizada limitada (padrão)
Um determinado texto é dividido em palavras-chave que são pesquisadas no banco de dados. Sempre que uma das palavras-chave existir, a linha correspondente será incluída no conjunto de resultados.
/api/books?_q=The Lord of the Rings
O exemplo acima retorna cada linha que contém uma das palavras-chave The
, Lord
, of
, the
, Rings
em uma de suas colunas. As colunas a serem consideradas na pesquisa de texto completo são passadas para parseMultiple
.
Implementação nativa do MySQL
Se a sua versão do MySQL suporta pesquisa de texto completo para o mecanismo que você usa, você pode usar esta pesquisa avançada no manipulador da API.
Basta alterar a opção de configuração de fulltext
para native
e certificar-se de que haja um índice de texto completo adequado nas colunas que você passa para parseMultiple
.
Cada resultado também conterá uma coluna _score
que permite classificar os resultados de acordo com o quão bem eles correspondem aos termos de pesquisa. Por exemplo
/api/books?_q=The Lord of the Rings&_sort=-_score
Você pode ajustar o nome desta coluna modificando a configuração fulltext_score_column
no arquivo de configuração.
Para definir a quantidade máxima de conjuntos de dados no resultado, use _limit
.
/api/books?_limit=50
Para definir o deslocamento dos conjuntos de dados no resultado, use _offset
.
/api/books?_offset=20&_limit=50
Esteja ciente de que para usar offset
você sempre deve especificar um limit
também. MySQL lança um erro para definição de deslocamento sem limite.
O manipulador de API também oferece suporte a relacionamentos Eloquent. Então se você quiser obter todos os livros com seus autores, basta adicionar os autores ao parâmetro _with
.
/api/books?_with=author
Relacionamentos também podem ser aninhados:
/api/books?_with=author.awards
Para que isso funcione, você precisa adicionar a anotação @Relation
a cada um dos seus métodos de relação, como:
/**
* @Relation
*/
public function author () {
return $ this -> belongsTo ( ' Author ' );
}
Isto é necessário por razões de segurança, para que apenas métodos de relação real possam ser invocados usando _with
.
Nota: Sempre que você limitar os campos com _fields
em combinação com _with
. Nos bastidores, os campos são estendidos com as chaves primárias/estrangeiras da relação. O Eloquent precisa das chaves de ligação para obter modelos relacionados.
É possível adicionar informações adicionais a uma resposta. Atualmente existem dois tipos de contagens que podem ser adicionadas aos cabeçalhos de resposta.
A total-count
que representa a contagem de todos os elementos de um recurso ou, para ser mais específico, a contagem na instância do construtor de consultas originalmente passada. A filter-count
que também leva em consideração os filtros. Eles podem, por exemplo, ser úteis para implementar a paginação.
/api/books?id-gt=5&_config=meta-total-count,meta-filter-count
Todos os metacampos são fornecidos no cabeçalho de resposta por padrão. Os seguintes cabeçalhos personalizados são usados:
Configuração | Cabeçalho |
---|---|
contagem metatotal | Contagem Meta-Total |
contagem de meta-filtro | Contagem de meta-filtros |
Por padrão, os metadados são incluídos no cabeçalho da resposta. Se você quiser ter tudo junto no corpo da resposta, você pode solicitar o chamado "envelope", incluindo response-envelope
no parâmetro _config
ou substituindo o config.php
padrão do pacote.
O envelope tem a seguinte estrutura:
{
"meta" : {
},
"data" : [
]
}