Histórico da Página
Classe base para criação de adapters utilizados em serviços REST suportando filtros de paginação e filtros baseados no padrão oData.
Índice | ||
---|---|---|
|
...
Métodos:
New
Descrição
Método construtor da classe
...
Retorno Logico, Se foi construído corretamente
...
AddMapFields
Descrição
Adiciona campo a campo as configurações de campos utilizado no Adapter
...
Aviso | |||||||||
---|---|---|---|---|---|---|---|---|---|
| |||||||||
O parâmetro
|
...
SetQuery
Descrição
Informa a query para a geração do Json
...
Deverá ser utilizado os Id's:
#QueryFields# Campos do SELECT, existe tratamento para o FIELDS no QueryParam
#QueryWhere# Condições do WHERE, existe tratamento para FILTER no QueryParam
...
SetWhere
Descrição
Faz o set da condição de filtro utilizada para ordenação do ResultSet, substitui o id #QueryWhere#
...
Nome | Tipo | Descrição |
---|---|---|
cWhere | Carácter | String contendo as condições do where para o ResultSet, substitui o id #QueryWhere# |
...
SetOrder
Descrição
Faz o set da condição padrão utilizada para ordenação do ResultSet
...
Nome | Tipo | Descrição |
---|---|---|
cOrder | Carácter | String contendo a ordenação que irá ser utilizada no ResultSet |
...
SetOrderQuery
Descrição
String contendo a ordenação informada via QueryParam
...
Nome | Tipo | Descrição |
---|---|---|
cOrder | Carácter | String contendo a ordenação que irá ser utilizada no ResultSet. Obs.: Adicione "-" a esquera do cOrder para ordenar decrescente (ex.: "-filial"). |
...
SetFields
Descrição
Informa os campos que serão utilizados para geração do Json
...
Nome | Tipo | Descrição |
---|---|---|
cFields | Carácter | Campos que serão exportados para o Json, utilizado para setar os campos informados via QueryParam |
...
Execute
Descrição
Realiza o parse dos ids #QueryFields# e #QueryWhere# gerando o ResultSet
...
Retorno Logico, Retorna se a execução foi realizada com sucesso
...
FillGetResponse
Descrição
Método chamado linha a linha do ResultSet para geração do Json
...
SetPage
Descrição
Configura qual pagina sera retornada pelo adapter
...
Nome | Tipo | Descrição |
---|---|---|
nPage | Numérico | Número da pagina a ser retornada |
...
SetPageSize
Descrição
Configura o tamanho da pagina
...
Nome | Tipo | Descrição |
---|---|---|
nPageSize | Numérico | Tamanho da página |
...
SetUrlFilter
Descrição
Faz a definição do filtro informado via parâmetros de query.
...
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
// filtros simples // a requição com: ?propriedade1=valor1&propriedade2=valor2 // exigiria o array como aUrlFilter := { ; {"propriedade1", "valor1"},; {"propriedade2", "valor2"} ; } self:SetUrlFilter(aUrlFilter) // filtro complexos // ?filter=propriedade1 eq 'valor1' and propriedade2 eq 'valor2' aUrlFilter := { ; {"FILTER", "propriedade1 eq 'valor1' and propriedade2 eq 'valor2'"}; } self:SetUrlFilter(aUrlFilter) // Rest Advpl // Essa versão do Rest já possui preparado um array com os parâmetros de query no formato adequado // Com isso é possível indicar diretamento o atributo da classe aQueryString self:SetUrlFilter(self:aQueryString) |
...
...
SetStyleReturn
Descrição
Irá retornar o Json
Retorno Carácter, Resposta da API
Exemplo de utilização com a tabela de produtos:
Classe de criação do adapter
Permite configurar o nome da propriedade de retorno dos itens da listagem do verbo GET.
Por padrão, o JSON retornado tem a propriedade items, esse método permite trocar o nome dessa propriedade.
Parâmetros
Nome | Tipo | Descrição |
---|---|---|
cPropItems | Carácter | Nome da propriedade de retorno dos itens no JSON de listagem do verbo GET do adapter |
Exemplo
oAdapter:SetStyleReturn("data")
Observação
Esse método está disponível somente para lib igual ou superior a 20221010
...
GetJSONResponse
Descrição
Irá retornar o Json
Retorno Carácter, Resposta da API
...
setIsCaseSensitive
Descrição
Indica que as propriedades do json são case sensitive.
Exemplo
oAdapter:setIsCaseSensitive(.T.)
Observação
Esse método está disponível somente para lib igual ou superior a 20230515
...
setUseSpaces
Descrição
Indica se considera os espaços à esquerda no retorno dos registros.
Exemplo
oAdapter:setUseSpaces(.T.)
Observação
Esse método está disponível somente para lib igual ou superior a 20230127
...
SetTlppFilter
Descrição
Definição de filtro para api tlpp onde os parâmetros recebidos vem no formato de json
Converte o objeto json em um array, e repassa para o metodo SetUrlFilter internamente
para ser usado em apis tlpp
Exemplo
jQueryParams := oRest:getQueryRequest()
oAdapter:SetTlppFilter(jQueryParams)
Observação
Esse método está disponível somente para lib igual ou superior a 20230515
...
Filtros complexos
Descrição
Filtros que são suportados pela classe, esses podem ser informados durante o consumo da API.
Lista
- STARTSWITH
- startswith(nome, 'JOAO')
- ENDSWITH
- endswith(nome, 'SILVA')
- CONTAINS
- contains(nome, 'SILVA')
- TOUPPER
- toupper(nome) eq 'JOAO DA SILVA'
- TOLOWER
- tolower(nome) eq 'joao da silva'
Exemplo genérico
- contains(tolower(nome), 'joao') or endswith(cpf, '002')
Observação
Alguns filtros foram implementados em datas diferentes de outros, logo é bom verificar qual filtro está disponível conforma data de sua lib.
O campo data pode ter comportamentos diferentes por conta do dado ser gravado no banco de dados como character.
...
Exemplos
Exemplo de utilização com a tabela de produtos:
Classe de criação do adapter
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#include 'totvs.ch'
#include 'parmtype.ch'
//-------------------------------------------------------------------
/*/{Protheus.doc} PrdAdapter
Classe Adapter para o serviço
@author Anderson Toledo
/*/
//-------------------------------------------------------------------
CLASS PrdAdapter FROM FWAdapterBaseV2
METHOD New()
METHOD GetListProd()
EndClass
Method New( cVerb ) CLASS PrdAdapter
_Super:New( cVerb, .T. )
return
Method GetListProd( ) CLASS PrdAdapter
Local aArea AS ARRAY
Local cWhere AS CHAR
aArea := FwGetArea()
//Adiciona o mapa de campos Json/ResultSet
AddMapFields( self )
//Informa a Query a ser utilizada pela API
::SetQuery( GetQuery() )
//Informa a clausula Where da Query
cWhere := " B1_FILIAL = '"+ FWxFilial('SB1') +"' AND SB1.D_E_L_E_T_ = ' '"
::SetWhere( cWhere )
//Informa a ordenação padrão a ser Utilizada pela Query
::SetOrder( "B1_COD" )
//Executa a consulta, se retornar .T. tudo ocorreu conforme esperado
If ::Execute()
// Gera o arquivo Json com o retorno da Query
::FillGetResponse()
EndIf
FwrestArea(aArea)
Return
Static Function AddMapFields( oSelf )
oSelf:AddMapFields( 'CODE' , 'B1_COD' , .T., .T., { 'B1_COD', 'C', TamSX3( 'B1_COD' )[1], 0 } )
oSelf:AddMapFields( 'DESCRIPTION' , 'B1_DESC' , .T., .F., { 'B1_DESC', 'C', TamSX3( 'B1_DESC' )[1], 0 } )
oSelf:AddMapFields( 'GROUP' , 'B1_GRUPO', .T., .F., { 'B1_GRUPO', 'C', TamSX3( 'B1_GRUPO' )[1], 0 } )
oSelf:AddMapFields( 'GROUPDESCRIPTION' , 'BM_DESC' , .T., .F., { 'BM_DESC', 'C', TamSX3( 'BM_DESC' )[1], 0 } )
Return
Static Function GetQuery()
Local cQuery AS CHARACTER
//Obtem a ordem informada na requisição, a query exterior SEMPRE deve ter o id #QueryFields# ao invés dos campos fixos
//necessáriamente não precisa ser uma subquery, desde que não contenha agregadores no retorno ( SUM, MAX... )
//o id #QueryWhere# é onde será inserido o clausula Where informado no método SetWhere()
cQuery := " SELECT #QueryFields#"
cQuery += " FROM " + RetSqlName( 'SB1' ) + " SB1 "
cQuery += " LEFT JOIN " + RetSqlName( 'SBM' ) + " SBM"
cQuery += " ON B1_GRUPO = BM_GRUPO"
cQuery += " AND BM_FILIAL = '"+ FWxFilial( 'SBM' ) +"'"
cQuery += " AND SBM.D_E_L_E_T_ = ' '"
cQuery += " WHERE #QueryWhere#"
Return cQuery |
Criação do serviço que irá executar o adapter
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
#include "totvs.ch"
#include "restful.ch"
//-------------------------------------------------------------------
/*/{Protheus.doc} products
Declaração do ws products
@author Anderson Toledo
/*/
//-------------------------------------------------------------------
WSRESTFUL products DESCRIPTION 'endpoint products API' FORMAT "application/json,text/html"
WSDATA Page AS INTEGER OPTIONAL
WSDATA PageSize AS INTEGER OPTIONAL
WSDATA Order AS CHARACTER OPTIONAL
WSDATA Fields AS CHARACTER OPTIONAL
WSMETHOD GET ProdList;
DESCRIPTION "Retorna uma lista de produtos";
WSSYNTAX "/api/v1/products" ;
PATH "/api/v1/products" ;
PRODUCES APPLICATION_JSON
END WSRESTFUL
WSMETHOD GET ProdList QUERYPARAM Page WSREST products
Return getPrdList(self)
Static Function getPrdList( oWS )
Local lRet as logical
Local oProd as object
DEFAULT oWS:Page := 1
DEFAULT oWS:PageSize := 10
DEFAULT oWS:Fields := ""
lRet := .T.
//PrdAdapter será nossa classe que implementa fornecer os dados para o WS
// O primeiro parametro indica que iremos tratar o método GET
oProd := PrdAdapter():new( 'GET' )
//o método setPage indica qual página deveremos retornar
//ex.: nossa consulta tem como resultado 100 produtos, e retornamos sempre uma listagem de 10 itens por página.
// a página 1 retorna os itens de 1 a 10
// a página 2 retorna os itens de 11 a 20
// e assim até chegar ao final de nossa listagem de 100 produtos
oProd:setPage(oWS:Page)
// setPageSize indica que nossa página terá no máximo 10 itens
oProd:setPageSize(oWS:PageSize)
// SetOrderQuery indica a ordem definida por querystring
oProd:SetOrderQuery(oWS:Order)
// setUrlFilter indica o filtro querystring recebido (pode se utilizar um filtro oData)
oProd:SetUrlFilter(oWS:aQueryString )
// SetFields indica os campos que serão retornados via querystring
oProd:SetFields( oWS:Fields )
// Esse método irá processar as informações
oProd:GetListProd()
//Se tudo ocorreu bem, retorna os dados via Json
If oProd:lOk
oWS:SetResponse(oProd:getJSONResponse())
Else
//Ou retorna o erro encontrado durante o processamento
SetRestFault(oProd:GetCode(),oProd:GetMessage())
lRet := .F.
EndIf
//faz a desalocação de objetos e arrays utilizados
oProd:DeActivate()
oProd := nil
Return lRet |
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
#include "fw-tlpp-core.th"
//-------------------------------------------------------------------
/*/{Protheus.doc} zGroup
API teste consulta Group
@author Caio Lima
@since 19/04/2023
//-----------------------------------------------------------------*/
Class zGroup
public method new() as object
@Get("/api/framework/zGroup")
public method getZGroup() as Logical
private Method callAdapter() as logical
EndClass
//-------------------------------------------------------------------
/*/{Protheus.doc} New
Metodo construtor da classe
@return object, self
@author Caio Lima
@since 19/04/2023
//-----------------------------------------------------------------*/
Method new() as object Class zGroup
Return self
//-------------------------------------------------------------------
/*/{Protheus.doc} getZGroup
api para listar usuários x funções x privilégios
@return logical, true caso deu certo a execução, do contrario retorna false
@author Caio Lima
@since 19/04/2023
//-----------------------------------------------------------------*/
Method getZGroup() as logical Class zGroup
Return(::callAdapter("Group", "displayName"))
//-------------------------------------------------------------------
/*/{Protheus.doc} callAdapter
realiza as definições que são comuns para todos os adapters
@param cAdapter, adapter a ser chamado
@param cOrder, order default a ser utilizada caso não tenha sido definido na chamada
@return logical, true caso tenha dado tudo certo na requisição, do contrario retorna falso
@author Caio Lima
@since 19/04/2023
//-----------------------------------------------------------------*/
Method callAdapter(cAdapter as character, cOrder as character) as logical Class zGroup
Local jQueryParams as json
Local oAdapter as object
Local lCalcTrueHasNext as logical
Local lTOk as logical
lTOk := .T.
Default cOrder := "user_id"
Default lIsUsrLogado := .F.
lCalcTrueHasNext := .T.
oRest:setKeyHeaderResponse("Content-Type", "application/json")
jQueryParams := oRest:getQueryRequest()
if cAdapter == "Group"
oAdapter := totvs.framework.adapter.groups():new( 'GET' )
EndIf
if jQueryParams:HasProperty("pagesize")
oAdapter:setPageSize(Val(jQueryParams["pagesize"]))
Else
oAdapter:setPageSize( 25 )
endif
if jQueryParams:HasProperty("order")
oAdapter:SetOrderQuery(jQueryParams["order"])
else
oAdapter:SetOrderQuery(cOrder)
endif
if jQueryParams:HasProperty("page")
oAdapter:setPage(Val(jQueryParams["page"]))
Else
oAdapter:setPage(1)
endif
oAdapter:SetQSearchPar()
oAdapter:SetTlppFilter(jQueryParams)
oAdapter:oJsonObj:CalcTrueHasNext(lCalcTrueHasNext)
If lTOk
oAdapter:getList()
If oAdapter:IsOk()
oRest:setResponse( oAdapter:gtJsonObjResponse():ToJson() )
Else
lTOk := .F.
setRestFault(oAdapter:getCode(),oAdapter:getMessage())
EndIf
EndIf
oAdapter:deActivate()
FwFreeObj(oAdapter)
Return(.T.)
|
Exemplo com utilização de r_e_c_n_o_ e substr, a utilização de funções SQL pode exigir a necessidade de fazer uma subquery.
Sub-query também é util em casos onde se deseja utilizar a mesma tabela mais de uma vez na query.
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#include "protheus.ch"
//-------------------------------------------------------------------
/*/{Protheus.doc} NaturezasAdapter
Classe Adapter para o serviço de Naturezas SED
@author Daniel Mendes
@version 1.0
@since 07/09/2023
/*/
//-------------------------------------------------------------------
class NaturezasAdapter from FWAdapterBaseV2
private data lAllFields as logical
public method new()
public method setAllFields()
public method getListNaturezas()
endclass
//-------------------------------------------------------------------
/*/{Protheus.doc} new
Construtor da classe
@return self, object, instância da classe
@type method
@author Daniel Mendes
@version 1.0
@since 07/09/2023
/*/
//-------------------------------------------------------------------
method new( cVerb as character) as object class NaturezasAdapter
_Super:New(cVerb, .T.)
self:lAllFields := .F.
return
//-------------------------------------------------------------------
/*/{Protheus.doc} setAllFields
Efetua o set para retornar os campos de função e recno
@return lAllFields, logical, indica o retorno dos campos de função SQL e recno
@type method
@author Daniel Mendes
@version 1.0
@since 07/09/2023
/*/
//-------------------------------------------------------------------
method setAllFields(lAllFields as logical) class NaturezasAdapter
self:lAllFields := lAllFields
return
//-------------------------------------------------------------------
/*/{Protheus.doc} getListNaturezas
Executa o adapter
@type method
@author Daniel Mendes
@version 1.0
@since 07/09/2023
/*/
//-------------------------------------------------------------------
method getListNaturezas() class NaturezasAdapter
local cWhere as character
AddMapFields(self, self:lAllFields)
::SetQuery(GetQuery(self:lAllFields))
cWhere := " SED.ED_FILIAL = '"+ FWxFilial("SED") +"' AND SED.D_E_L_E_T_ = ' '"
::SetWhere( cWhere )
::SetOrder( "ED_CODIGO" )
::setIsCaseSensitive(.T.) //Mantém o case no JSON de resposta
if ::Execute()
::FillGetResponse()
endif
return
| ||||||||
Bloco de código | ||||||||
#include 'totvs.ch' #include 'parmtype.ch' //------------------------------------------------------------------- /*/{Protheus.doc} PrdAdapter Classe Adapter para o serviço @author Anderson Toledo addMapFields Adiciona os campos do adapter @param oSelf, object, objeto do adapter @param lAllFields, logical, indica o retorno dos campos de função SQL e recno @type function @author Daniel Mendes @version 1.0 @since 07/09/2023 /*/ //------------------------------------------------------------------- CLASSstatic PrdAdapter FROM FWAdapterBaseV2 METHOD New() METHOD GetListProd() EndClass Method New( cVerb ) CLASS PrdAdapter _Super:New( cVerb, .T. ) return Method GetListProd( ) CLASS PrdAdapter Local aArea AS ARRAY Local cWhere AS CHAR aArea := FwGetArea() //Adiciona o mapa de campos Json/ResultSet AddMapFields( self ) //Informa a Query a ser utilizada pela API ::SetQuery( GetQuery() ) //Informa a clausula Where da Query cWhere := " B1_FILIAL = '"+ FWxFilial('SB1') +"' AND SB1.D_E_L_E_T_ = ' '" ::SetWhere( cWhere ) //Informa a ordenação padrão a ser Utilizada pela Query ::SetOrder( "B1_COD" ) //Executa a consulta, se retornar .T. tudo ocorreu conforme esperado If ::Execute() // Gera o arquivo Json com o retorno da Query ::FillGetResponse() EndIf FwrestArea(aArea) Return Static Function AddMapFields( oSelf ) oSelf:AddMapFields( 'CODE'function addMapFields(oSelf as object, lAllFields as logical) oSelf:AddMapFields("code" , "ED_CODIGO" , .T., .T., { "ED_CODIGO", "C", TamSX3("ED_CODIGO")[1], 0 } ) oSelf:AddMapFields("description" , "ED_DESCRIC" , .T., .F., { "ED_DESCRIC", "C", TamSX3("ED_DESCRIC")[1], 0 } ) if lAllFields oSelf:AddMapFields("recnoNickname" , "RECNO_NICK" , .T., .F., { "RECNO_NICK", "N", 16, 0 }) //Com "apelido" no campo oSelf:AddMapFields("recno" , "RECNO" , 'B1_COD' , .T., .TF., { 'B1_COD', 'C', TamSX3( 'B1_COD' )[1], 0 } ) oSelf:AddMapFields( 'DESCRIPTION' , 'B1_DESC'"RECNO", "N", 16, 0 }, "R_E_C_N_O_") //Com campo especial oSelf:AddMapFields("subStrDescription" , "SUBSTR_DESC" , .T., .F., { 'B1"SUBSTR_DESC'", '"C'", TamSX3( 'B1_DESC' )[1]5, 0 } ) oSelf:AddMapFields( 'GROUP' , 'B1_GRUPO', .T., .F., { 'B1_GRUPO', 'C', TamSX3( 'B1_GRUPO' )[1], 0 } ) oSelf:AddMapFields( 'GROUPDESCRIPTION' , 'BM_DESC' , .T., .F., { 'BM_DESC', 'C', TamSX3( 'BM_DESC' )[1], 0 } ) Return Static Function GetQuery() Local cQuery AS CHARACTER //Obtem a ordem informada na requisição, a query exterior SEMPRE deve ter o id #QueryFields# ao invés dos campos fixos //necessáriamente não precisa ser uma subquery, desde que não contenha agregadores no retorno ( SUM, MAX... ) //o id #QueryWhere# é onde será inserido o clausula Where informado no método SetWhere() //Com função SQL endif return //------------------------------------------------------------------- /*/{Protheus.doc} getQuery Retorna a query do Adapter @param lAllFields, logical, indica o retorno dos campos de função SQL e recno @return cQuery, character, Query da SED @type function @author Daniel Mendes @version 1.0 @since 07/09/2023 /*/ //------------------------------------------------------------------- static function getQuery(lAllFields as logical) as character local cQuery as character local cTable as character cTable := RetSqlName("SED") cQuery := " SELECT #QueryFields#" cQuery += " FROM " FROM " if lAllFields cQuery += RetSqlName" ( 'SB1' ) + " SB1 SELECT ED_FILIAL, ED_CODIGO, ED_DESCRIC, R_E_C_N_O_ RECNO_NICK, " cQuery += " LEFT JOIN " + RetSqlName( 'SBM' ) + " SBM" cQuery += " ON B1_GRUPO = BM_GRUPO" cQuery += " AND BM_FILIAL = '"+ FWxFilial( 'SBM' ) +"'" cQuery += " AND SBM.D_E_L_E_T_ = ' '" SUBSTR(ED_DESCRIC, 1 , 5) SUBSTR_DESC, R_E_C_N_O_, D_E_L_E_T_ " cQuery += " FROM " + cTable + " ) " else cQuery += cTable endif cQuery += " SED " cQuery += " WHERE #QueryWhere#" Returnreturn cQuery |
Criação do serviço que irá executar o adapter
|
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#include "totvsprotheus.ch" #include "restful.ch" //------------------------------------------------------------------- /*/{Protheus.doc} products Declaração do ws products @author Anderson Toledonaturezas Serviço REST de Naturezas com Adapter @author Daniel Mendes @version 1.0 @since 07/09/2023 /*/ //------------------------------------------------------------------- WSRESTFULwsrestful productsnaturezas DESCRIPTIONdescription 'endpoint productsnaturezas API' FORMATformat "application/json,text/html" WSDATAwsdata Page ASas INTEGERinteger OPTIONALoptional WSDATAwsdata PageSize ASas INTEGERinteger OPTIONALoptional WSDATAwsdata Order ASas CHARACTERcharacter OPTIONALoptional WSDATAwsdata Fields ASas CHARACTERcharacter OPTIONALoptional WSMETHODwsmethod GETget ProdListNatV1List; DESCRIPTIONdescription "Retorna uma lista de produtosnaturezas"; WSSYNTAXwssyntax "/api/v1/productsnaturezas" ; PATHpath "/api/v1/productsnaturezas" ; PRODUCES APPLICATION_JSON END WSRESTFUL WSMETHOD GET ProdList QUERYPARAM Page WSREST products Return getPrdList(self) Static Function getPrdList( oWS ) produces APPLICATION_JSON wsmethod get NatV2List; Local lRet as logical description "Retorna Localuma oProdlista asde objectnaturezas"; DEFAULT oWS:Page wssyntax := 1"/api/v2/naturezas" ; DEFAULT oWS:PageSize := 10path "/api/v2/naturezas" ; DEFAULT oWS:Fields := ""produces APPLICATION_JSON lRet := .T. //PrdAdapter será nossa classe que implementa fornecer os dados para o WS // O primeiro parametro indica que iremos tratar o método GET oProd := PrdAdapter():new( 'GET' ) //o método setPage indica qual página deveremos retornar //ex.: nossa consulta tem como resultado 100 produtos, e retornamos sempre uma listagem de 10 itens por página. // a página 1 retorna os itens de 1 a 10 // a página 2 retorna os itens de 11 a 20 // e assim até chegar ao final de nossa listagem de 100 produtos oProd:setPage(oWS:Page) // setPageSize indica que nossa página terá no máximo 10 itens oProd:setPageSize(oWS:PageSize) // SetOrderQuery indica a ordem definida por querystring oProd:SetOrderQuery(oWS:Order) // setUrlFilter indica o filtro querystring recebido (pode se utilizar um filtro oData) oProd:SetUrlFilter(oWS:aQueryString ) // SetFields indica os campos que serão retornados via querystring oProd:SetFields( oWS:Fields ) // Esse método irá processar as informações oProd:GetListProd() //Se tudo ocorreu bem, retorna os dados via Json If oProd:lOk oWS:SetResponse(oProd:getJSONResponse()) Else //Ou retorna o erro encontrado durante o processamento SetRestFault(oProd:GetCode(),oProd:GetMessage()) lRet := .F. EndIf //faz a desalocação de objetos e arrays utilizados oProd:DeActivate() oProd := nil Return lRet end wsrestful //------------------------------------------------------------------- /*/{Protheus.doc} NatV1List Verbo GET da API de Naturezas @return logical, indica sucesso na requisição @type method @author Daniel Mendes @version 1.0 @since 07/09/2023 /*/ //------------------------------------------------------------------- wsmethod get NatV1List queryparam Page wsrest naturezas return getNaturezasList(self, .F.) //------------------------------------------------------------------- /*/{Protheus.doc} NatV2List Verbo GET da API de Naturezas @return logical, indica sucesso na requisição @type method @author Daniel Mendes @version 2.0 @since 07/09/2023 /*/ //------------------------------------------------------------------- wsmethod get NatV2List queryparam Page wsrest naturezas return getNaturezasList(self, .T.) //------------------------------------------------------------------- /*/{Protheus.doc} getNaturezasList Executa o adapter de Naturezas para o verbo GET @param oWS, object, objeto REST @param lAllFields, logical, indica o retorno dos campos de função SQL e recno @return lRet, logical, indica sucesso na requisição @type function @author Daniel Mendes @version 1.0 @since 07/09/2023 /*/ //------------------------------------------------------------------- static function getNaturezasList(oWS as object, lAllFields as logical) local lRet as logical local oNatSED as object default oWS:Page := 1 default oWS:PageSize := 10 default oWS:Fields := "" oNatSED := NaturezasAdapter():new("GET") oNatSED:setAllFields(lAllFields) oNatSED:setPage(oWS:Page) oNatSED:setPageSize(oWS:PageSize) oNatSED:setOrderQuery(oWS:Order) oNatSED:setUrlFilter(oWS:aQueryString) oNatSED:setFields(oWS:Fields) oNatSED:getListNaturezas() lRet := oNatSED:IsOk() if lRet oWS:SetResponse(oNatSED:getJSONResponse()) else SetRestFault(oNatSED:GetCode(),oNatSED:GetMessage()) EndIf oNatSED:DeActivate() FreeObj(oNatSED) oNatSED := nil return lRet |
A partir do exemplo acima é possível realizar filtros no retorno do GET, abaixo exemplos utilizando paginação e o padrão oData.
Obs. Endereço e conteúdo da comparação deve ser ajustado de acordo com o ambiente utilizado..
Filtro utilizando paginação
Bloco de código |
---|
http://localhost:8080/teste/rest/api/v1/products?pagesize=1&page=3 |
Filtro utilizando
...
o padrão oData
Bloco de código |
---|
http://localhost:8080/teste/rest/api/v1/products?pagesize=1&page=3 |
...
filter=code eq '000001' |
Filtro utilizando ordenação
Bloco de código |
---|
http://localhost:8080/teste/rest/api/v1/products?order=description |
Filtro informando os campos que serão retornados
Bloco de código |
---|
http://localhost:8080/teste/rest/api/v1/products?filter=code eq '000001' |
Filtro utilizando ordenação
Bloco de código |
---|
http://localhost:8080/teste/rest/api/v1/products?order=description |
Filtro informando os campos que serão retornados
?fields=code,description |
Informações | ||
---|---|---|
| ||
A partir da lib 20220322 é possível utilizar os filtros toupper e tolower: filter=toupper(description) eq 'XISTO' filter=tolower(description) eq 'xis' A partir da lib 20220502 o JSON de retorno do GET com listagem, além de possuir a propriedade hasNext indicando que ainda existem registros a serem retornados, contará também com a propriedade remainingRecords, que retornará quantos registros ainda existem para retorno, facilitando assim por exemplo o cálculo da quantidade de páginas existentes. | ||
Bloco de código | ||
http://localhost:8080/teste/rest/api/v1/products?fields=code,description |
Aviso | ||
---|---|---|
| ||
A classe não dá suporte ao campos memo que utilizam da SYP. |
Nota | ||
---|---|---|
| ||
A classe FWAdapterBaseV2 não faz uso da ChangeQuery, logo a utilização de concatenação e/ou funções SQL devem ser evitadas ou tratadas quando necessário. |