Error 500 - API REST

Pessoal, bom dia. Tenho uma API REST que me retorna um certo registro após informado um parâmetro em sua URL, os registros retornados são de uma tabela chamada ZZ0 (tabela customizada) nessa tabela guardamos informações de anexos amarrados por um identificador onde o mesmo faz referencia a cotações, basicamente temos a seguinte estrutura na tabela.

ZZ0FILIAL NOT NULL CHAR(2)ZZ0_NUM NOT NULL CHAR(6)ZZ0_EXTENS NOT NULL CHAR(10)ZZ0_ENCODE BLOBZZ0_NOME NOT NULL CHAR(100) ZZ0_USERGI NOT NULL CHAR(17)D_E_L_E_T NOT NULL CHAR(1)RE_C_N_O NOT NULL NUMBERRE_C_D_E_L NOT NULL NUMBER

A minha função faz o seguinte, ao informar um número ZZ0_NUM ela retorna dados como o próprio número e o ZZ0_NOME, até ai tudo bem, ele retorna corretamente os dados. O problema ocorre quando tento retornar as informações do campo ZZ0_ENCODE, onde os registros são do tipo BLOB e armazena o BASE64 dos meus arquivos que foram convertidos.

Abaixo segue estrutura da API.


WSMETHOD GET GetById PATHPARAM id WSSERVICE MeuRest
    Local lPost    := .T.
    Local oResponse := JsonObject():New()

    Local aTarefas := {}

    ::SetContentType("application/json")

    cAlias := GetNextAlias()
    cQuery := " SELECT "
    cQuery += "    ZZ0.ZZ0_NUM, "
    cQuery += "    ZZ0.ZZ0_NOME "
    cQuery += " FROM " + RetSqlName("ZZ0") + " ZZ0 "
    cQuery += " WHERE "
    cQuery += "     ZZ0.D_E_L_E_T_ = ' ' AND ZZ0.ZZ0_NUM = '"+::id+"' "


    MPSysOpenQuery(cQuery, cAlias)
    If (cAlias)->(!Eof())
        lPost := .T.
        oResponse['code'] := (cAlias)->ZZ0_NUM
        oResponse['description'] := (cAlias)->ZZ0_NOME
        cResponse := FWJsonSerialize(oResponse, .F., .F., .T.)
        ::SetResponse(cResponse)
    Else
        lPost := .F.
        cRetorno := "Cotacao não encontrado!"
        SetRestFault(404, cRetorno)
    EndIf
    (cAlias)->(DbCloseArea())
Return lPost

O retorno abaixo ilustra que a API está funcionando com os campos mencionados acima. sucesso.JPG

Após a troca do campo ZZ0_NOME pelo ZZ0_ENCODE é mostrado o seguinte erro.

Abaixo alteração no fonte:


WSMETHOD GET GetById PATHPARAM id WSSERVICE MeuRest
    Local lPost    := .T.
    Local oResponse := JsonObject():New()

    Local aTarefas := {}

    ::SetContentType("application/json")

    cAlias := GetNextAlias()
    cQuery := " SELECT "
    cQuery += "    ZZ0.ZZ0_NUM, "
    cQuery += "    ZZ0.ZZ0_ENCODE "
    cQuery += " FROM " + RetSqlName("ZZ0") + " ZZ0 "
    cQuery += " WHERE "
    cQuery += "     ZZ0.D_E_L_E_T_ = ' ' AND ZZ0.ZZ0_NUM = '"+::id+"' "


    MPSysOpenQuery(cQuery, cAlias)
    If (cAlias)->(!Eof())
        lPost := .T.
        oResponse['code'] := (cAlias)->ZZ0_NUM
        oResponse['description'] := (cAlias)->ZZ0_ENCODE
        cResponse := FWJsonSerialize(oResponse, .F., .F., .T.)
        ::SetResponse(cResponse)
    Else
        lPost := .F.
        cRetorno := "Cotacao não encontrado!"
        SetRestFault(404, cRetorno)
    EndIf
    (cAlias)->(DbCloseArea())
Return lPost

:warning: Atenção: Esta publicação foi transferida automaticamente do fórum antigo, mas os anexos não foram incluídos.

Quando ocorre o erro 500, normalmente sua API gerou exceção, qual erro ocorreu? Você consegue normalmente ver o erro no console.

Sim, ele retornou o seguinte erro → invalid field name in Alias SCGN000008->ZZ0_ENCODE on REST_MEUREST:GET_GETBYID(MEUREST.PRW) 14/04/2021 16:34:41 line : 83

Só não consegui entender ainda o motivo de reclamar que não existe o ZZ0-ENCODE.

Olá, Acredito que a API não está deixando você fazer mandar o campo do tipo BLOB, tente converter o BLOB para String na API mesmo, que acredito que vai.

Boa tarde Clodoaldo, mas no caso não poderia utilizar o cValToChar(), certo? Por ser um campo muito grande ele iria estourar o limite permitido.

Uma solução mais adequada e fazer o que o Daniel falou ZZ0.R_E_C_N_O_ RECNO

Matheus,

Os campos do tipo memo nem sempre podem ser retornados em query. Isso depende do tipo do campo, da versão do DBAccess, DBAPI etc.

Caso você não atenda um dos requisitos, o campo do tipo memo não será retornado, logo ao tentar utilizá-lo você terá o erro invalid field name in Alias.

Documentações:

https://tdn.totvs.com/display/tec/DBAccess+-+Perguntas+frequentes#DBAccess-Perguntasfrequentes-dbfaq

https://tdn.totvs.com/pages/viewpage.action?pageId=525011927


Alternativa

Quando o campo não pode ser retornado na query, uma alternativa é fazer a query e retornar o recno:


cQuery := " SELECT "
cQuery += "    ZZ0.ZZ0_NUM, "
cQuery += "    ZZ0.R_E_C_N_O_ RECNO "
cQuery += " FROM " + RetSqlName("ZZ0") + " ZZ0 "
cQuery += " WHERE "
cQuery += "     ZZ0.D_E_L_E_T_ = ' ' AND ZZ0.ZZ0_NUM = '"+::id+"' "

Após abrir a query, você vai até o registro via DBGoTo, pois com a workarea aberta, é possível efetuar a leitura do campo memo normalmente:


ZZ0->(DbGoTo((cAlias)->RECNO))
oResponse['description'] := ZZ0->ZZ0_ENCODE

Daniel, boa tarde.
Excelente, funcionou certinho como nos passou na alternativa… muito obrigado.