Histórico da Página
GitHUB → https://github.com/totvs/tlpp-sample-rest/tree/master/server/migrate-FWrest-2-tlpp
Como migrar um REST em FWREST para uso com Annotation (
...
Inclusão de trecho | ||||||
---|---|---|---|---|---|---|
|
Nesse projeto [ migrate-FWrest-2-tlpp ] iremos exemplificar através de códigos fontes em
...
Inclusão de trecho | ||||||
---|---|---|---|---|---|---|
|
Inclusão de trecho | ||||||
---|---|---|---|---|---|---|
|
A primeiro forma será como se cria um serviço REST utilizando o framework Protheus em
...
Inclusão de trecho | ||||||
---|---|---|---|---|---|---|
|
...
Inclusão de trecho | ||||||
---|---|---|---|---|---|---|
|
Sendo assim, teremos 3 (três) códigos fontes, sendo:
Pasta | Nome arquivo | Linguagem | Tecnologia | Estrutura |
---|---|---|---|---|
src\ | rest-mod01.prw |
...
| framework Protheus | classe para REST | |||||||||
src\ | rest-mod02.tlpp |
...
| annotation | user Function | |||||||||
src\ | rest-mod03.tlpp |
...
| annotation | classe genérica |
Características
Dependências técnicas
FWREST
- Binário Lobo-Guará
- Protheus
- Framework Protheus
- License Protheus
- Conhecimento de Classe
Annotation
- Binário Lobo-Guará 2. Core
...
3. Conhecimento de annotationInclusão de trecho TLPP TLPP nopanel true
Verbos HTTP suportados
- FWREST
- GET
...
- POST
- PUT
- DELETE
Annotation
...
GET
...
- POST
...
- PUT
...
- PATCH
...
- DELETE
Resumo das mudanças
Cabeçalho arquivo fonte
FWREST
#include 'totvs.ch' #include "restful.ch"
Annotation
#include "tlpp-core.th" #include "tlpp-rest.th"
Definição do Verbo HTTP
FWREST
Para utilizar o WSMETHOD é necessário criar antes WSRESTFUL, tal como é uma declaração de classes, porém com sintaxe específica para o REST.
WSMETHOD GET
Annotation
Nesse caso não há dependência de nenhuma classe e é possível utilizar em funções de usuários, funções e métodos de classes, ficando à gosto do desenvolvedor.
@Get()
EndPoint
FWREST
A composição para a definição de endpoints nessa versão é composta em dois elementos no fonte.
O primeiro é propriamente o nome da classe de Restful, sendo:
WSRESTFUL sampleMigrateRestProtheus
A outra parte é complementada através da definição da classe, sendo:
WSMETHOD POST ....... WSSYNTAX "/sampleMigrateRestProtheus/{id}"
Podendo ter alterações pelo comando PATH, ex:
WSMETHOD POST ........ PATH "/v2/sampleMigrateRestProtheus/{id}"
Annotation
Por esse modo, você pode criar o endpoint sem qualquer relação ao nome da classe ou função que será executada.
A definição do endpoint é através da propriedade "endpoint" da annotation, porém, como ela é a primeira propriedade, pode-se simplesmente colocar seu valor sem nomear a propriedade.
O exemplo abaixo é a forma simples de definir um endpoint:
@Get("/sampleMigrateRestTlpp")
Pode-se também, definir os path params como segue abaixo:
@Get("/sampleMigrateRestTlpp/:id")
Também é possível definir uma descrição para o endpoint, ex:
@Get(endpoint="/sampleMigrateRestTlpp",description="descrição do método Get")
Parâmetros [ Path Param ]
Essa é forma de passar valores através de URI como complementos dos paths, ex: http://localhost:8080/nomerest/cliente/:2345
No exemplo acima, 2345 é o path param para o ID do cliente.
FWREST
Esse modo é possível resgatar os valores de path param através da propriedade (array) ::aURLParms, conforme exemplo abaixo:
if len(::aURLParms) > 0 cId := ::aURLParms[1] endif
porém, não é possível buscar nominalmente o valor, e somente através da ordem que ele é declarado na URI.
Annotation
O objeto oRest possui um método específico para retornar somente os parâmetros recebidos via Path Param, sendo:
jPath := oRest:getPathParamsRequest()
O retorno do método é uma estrutura em Json com todos os parâmetros recebidos via path param, sendo assim, é possível resgatar o valor do parâmetro acessando seu valor diretamente no Json através do seu nome.
Veja abaixo:
cId := jPath[ 'id' ]
Parâmetros [ Query String ]
Essa é o modo de passar valores através de URL após todos os paths e de forma nomeada, ex: http://localhost:8080/nomerest/cliente?id=2345
No exemplo acima, o parâmetro leva o nome de "id" e tem o valor de 2345.
FWREST
Para que possa receber parâmetros via query string, é preciso declará-lo como um parâmetro que o método irá receber, como descrito abaixo:
WSRESTFUL sampleMigrateRestProtheus ...... WSDATA id AS CHARACTER OPTIONAL ....... WSMETHOD GET WSRECEIVE id .....
Após isso, pode-se utilizá-lo como abaixo:
// Para que não seja NIL DEFAULT ::id := '' // Acessa-se diretamente conout( ::id )
Annotation
O objeto oRest possui um método específico para retornar somente os parâmetros recebidos via query string, sendo:
jPath := oRest:getQueryRequest()
O retorno do método é uma estrutura em Json com todos os parâmetros recebidos via query string, sendo assim, é possível resgatar o valor do parâmetro acessando seu valor diretamente no Json através do seu nome.
Veja abaixo:
cId := jPath[ 'id' ]
Parâmetros [ Body HTTP ]
FWREST
cBody := ::GetContent()
Annotation
cBody := oRest:GetBodyRequest()
Return OK
FWREST
::SetResponse( cResponse )
Annotation
oRest:setResponse( cResponse )
Return Error
FWREST
SetRestFault( nCodeHttp, cMessage )
Annotation
oRest:setFault( cResponse )
Nesse caso o código HTTP do retorno será 500, caso tenha a necessidade de trocar o código HTTP, utilize antes o método conforme abaixo:
oRest:setStatusCode( nCodeHttp ) oRest:setFault( cResponse )
Exemplos
É importante ressaltar que para simplificar este manual iremos unificar os verbos HTTP "PUT", "POST" e "PATCH", pois possuem funcionalidades similares no uso em APIs em REST. Porém nos arquivos acima descritos todos os exemplos estarão presentes.
Exemplo GET
FWREST
WSRESTFUL sampleMigrateRestProtheus DESCRIPTION "Exemplo de REST framework Protheus" WSDATA id AS CHARACTER OPTIONAL WSMETHOD GET DESCRIPTION "método Get" WSSYNTAX "/sampleMigrateRestProtheus" END WSRESTFUL WSMETHOD GET WSRECEIVE id WSSERVICE sampleMigrateRestProtheus local cData := '' ::SetContentType("application/json") DEFAULT ::id := '' cData := '{ "METHOD" : "GET" ,"id" : "' + ::id + '" }' ::SetResponse( cData ) Return .T.
Annotation
@Get("/sampleMigrateRestTlpp") user function GETsampleMigrateRestTlpp() local cId := '' local cData := '' local jPath jPath := oRest:getQueryRequest() if ( jPath <> Nil ) cId := jPath[ 'id' ] if ( valtype(cId) == 'U' ) cId := '' endif endif cData := '{ "METHOD" : "GET" ,"id" : "' + cId + '" }' oRest:setResponse( cData ) return
Exemplo POST
FWREST
WSRESTFUL sampleMigrateRestProtheus DESCRIPTION "Exemplo de REST framework Protheus" WSMETHOD POST DESCRIPTION "método Post" WSSYNTAX "/sampleMigrateRestProtheus/{id}" END WSRESTFUL WSMETHOD POST WSSERVICE sampleMigrateRestProtheus local cId := '' local cBody := '' local jBody ::SetContentType("application/json") if len(::aURLParms) > 0 cId := ::aURLParms[1] endif ::SetResponse( '{ "METHOD" : "POST" ,"id" : "' + cId + '" ' ) cBody := ::GetContent() jBody := JsonObject():new() jBody:fromJson( cBody ) if ( jBody <> Nil ) if ( !empty(jBody:GetJsonText("cpo1")) ) ::SetResponse( ', "cpo1" : "' + jBody:GetJsonText("cpo1") + '" ' ) endif if ( !empty(jBody:GetJsonText("cpo2")) ) ::SetResponse( ', "cpo2" : "' + jBody:GetJsonText("cpo2") + '" ' ) endif endif ::SetResponse( ' }' ) Return .T.
Annotation
@Post("/sampleMigrateRestTlpp/:id") user function PostsampleMigrateRestTlpp() local cId := '' local cData := '' local jPath local jBody jPath := oRest:getPathParamsRequest() if ( jPath <> Nil ) cId := jPath[ 'id' ] if ( valtype(cId) == 'U' ) cId := '' endif endif cData := '{ "METHOD" : "POST" , "id" : "' + cId + '" ' jBody := JsonObject():new() jBody:fromJson( oRest:GetBodyRequest() ) if ( jBody <> Nil ) if ( !empty(jBody:GetJsonText("cpo1")) ) cData += ', "cpo1" : "' + jBody:GetJsonText("cpo1") + '" ' endif if ( !empty(jBody:GetJsonText("cpo2")) ) cData += ', "cpo2" : "' + jBody:GetJsonText("cpo2") + '" ' endif endif cData += '}' oRest:setResponse( cData ) return
Exemplo DELETE
FWREST
WSRESTFUL sampleMigrateRestProtheus DESCRIPTION "Exemplo de REST framework Protheus" WSMETHOD DELETE DESCRIPTION "método Delete" WSSYNTAX "/sampleMigrateRestProtheus/{id}" END WSRESTFUL WSMETHOD DELETE WSSERVICE sampleMigrateRestProtheus local cId := '' local cData := '' ::SetContentType("application/json") if len(::aURLParms) > 0 cId := ::aURLParms[1] endif cData := '{ "METHOD" : "DELETE" ,"id" : "' + cId + '" }' ::SetResponse( cData ) Return .T.
Annotation
@Delete("/sampleMigrateRestTlpp/:id") user function DeletesampleMigrateRestTlpp() local cId := '' local cData := '' local jPath jPath := oRest:getPathParamsRequest() if ( jPath <> Nil ) cId := jPath[ 'id' ] if ( valtype(cId) == 'U' ) cId := '' endif endif cData := '{ "METHOD" : "DELETE" , "id" : "' + cId + '" ' + '}' oRest:setResponse( cData ) return
Incluir Página | ||||
---|---|---|---|---|
|