DEV Community

Josimar Junior
Josimar Junior

Posted on • Edited on

Um microblog usando Protheus - Rest Server, parte 3, serviço padrão rest de modelos mvc

Introdução

Nesta parte será apresentado o serviço de rest padrão que é oferecido quando utilizado MVC.
Para um bom entendimento de como funciona é importante que a pessoa esteja familiarizada com a construção de modelos de dados para MVC.
O conteúdo disponível oficialmente sobre MVC está no link.

Essa parte é continuação da anterior e portanto caso tenha chegado até aqui sem ler a parte anterior, sugiro olhar ao menos a estrutura da tabela ZT0 - Perfis.
Segunda parte

A construção do modelo de dados

O modelo de dados para este caso é bem simples, como a tabela possui poucos campos e ainda não foi adicionada validação alguma, somente recuperar a estrutura e definir os ids para os componentes é exigido.

O ModelDdef ficou assim:

static function ModelDef()
    local oModel   as object
    local oStrZT0  as object

    oStrZT0 := FWFormStruct(1, "ZT0")
    oModel := MpFormModel():New("ZMBMODEL")

    oModel:AddFields("ZT0_FIELDS", , oStrZT0)
    oModel:SetDescription("Cadastro de perfis")
    oModel:GetModel("ZT0_FIELDS"):SetDescription("Perfis")
return oModel
Enter fullscreen mode Exit fullscreen mode

Os detalhes importantes neste modelo são:

  • as descrições para o modelo completo e para o cabeçalho/enchoice;
  • o id como ZMBMODEL, este id define qual o nome da função de usuário para os ponto de entradas que este modelo vai invocar e portanto, colocar com o mesmo nome do fonte faria acontecer alguns comportamentos inusitados (menu não aparecer, programa travar, erro durante carga, etc). Com o que foi definido nesse modelo os ponto de entradas serão encontrados pela função U_ZMBMODEL.

Só com a definição do modelo não acontece a publicação do serviço rest do MVC, para isso é necessário adicionar os comandos PUBLISH USER MODEL ou PUBLISH MODEL, respectivamente para funções de usuário e funções do padrão.

A documentação sobre os recursos oferecidos quando estes comandos são adicionados a fontes compilados estão descritos nessas documentações.
Publicando um modelo como rest
FwRestModel

Nesta publicação não será explicado o modelo mais avançado indicado pela segundo documentação, contudo serão explicadas as possibilidades criadas com esta forma avançada.
Dica: modelos que possuem "condições" para a montagem de sua estrutura têm grandes chances de sofrer com comportamentos inadequados e erros, pois as threads para resposta dos serviços de rest raramente têm as mesmas variáveis públicas preenchidas quando comparadas com a execução por tela/smartclient, por isso evite condições na montagem do seu modelo de dados.

Fazendo a publicação de um modelo

Para o modelo MVC do cadastro de Perfis foi realizada duas publicações de serviços: uma com o id perfis e outra com o id ZMBA010.
Os comandos que fizeram estas publicações foram:

// http://localhost:18085/rest/fwmodel/Perfis/
PUBLISH USER MODEL REST NAME Perfis SOURCE ZMBA010

// http://localhost:18085/rest/fwmodel/ZMBA010/
PUBLISH USER MODEL REST NAME ZMBA010 SOURCE ZMBA010
Enter fullscreen mode Exit fullscreen mode

Após a compilação do arquivo com estas instruções e o ambiente configurado para atender a requisições REST, fica disponível na URI .../fwmodel/ZMBA010/{chave} a recuperação de dados e informações sobre o cadastro MVC.
Essa URI é a padrão para qualquer programa, portanto qualquer programa que teve seu modelo publicado ficará acessível a partir da URI /fwmodel/{programa}/{chave}.

Explorando o modelo exposto

Três endpoints são disponibilizados para permitir a leitura e análise de informações sobre o modelo publicado.

  • /schema - retorna a documentação da estrutura dos campos que inclui o nome, o tipo, o tamanho, etc. Traz bastante informação sobre o modelo de dados.
  • /xmldata - retorna a estrutura de um item para ser utilizado posteriormente nas operações de POST e PUT.
<?xml version="1.0" encoding="UTF-8"?>
<ZMBMODEL Operation="1" version="1.01">
    <ZT0_FIELDS modeltype="FIELDS">
        <ZT0_FILIAL order="1">
            <value></value>
        </ZT0_FILIAL>
        <ZT0_USRID order="2">
            <value></value>
        </ZT0_USRID>
        <ZT0_EMAIL order="3">
            <value></value>
        </ZT0_EMAIL>
        <ZT0_NOME order="4">
            <value></value>
        </ZT0_NOME>
    </ZT0_FIELDS>
</ZMBMODEL>
Enter fullscreen mode Exit fullscreen mode
  • /xmldatadetail - retorna a estrutura de um item (como o anterior) e com detalhes adicionais como tamanho, tipo do dado, título e obrigatoriedade.
<?xml version="1.0" encoding="UTF-8"?>
<ZMBMODEL Operation="1" version="1.01">
    <ZT0_FIELDS modeltype="FIELDS">
        <ZT0_FILIAL order="1" len="2,0" datatype="C" info="Filial" >
            <value></value>
        </ZT0_FILIAL>
        <ZT0_USRID order="2" len="6,0" datatype="C" info="cod usuário" obrigat="1" >
            <value></value>
        </ZT0_USRID>
        <ZT0_EMAIL order="3" len="100,0" datatype="C" info="email" obrigat="1" >
            <value></value>
        </ZT0_EMAIL>
        <ZT0_NOME order="4" len="100,0" datatype="C" info="nome" obrigat="1" >
            <value></value>
        </ZT0_NOME>
    </ZT0_FIELDS>
</ZMBMODEL>
Enter fullscreen mode Exit fullscreen mode

Estes endpoints somente retornam no formato application/xml.

Recuperando dados usando o modelo

Os métodos e operações permitidos estão na tabela a seguir.

método path objetivo usa informação do...
POST /fwmodel/Perfis/ incluir um registro body
GET /fwmodel/Perfis/ incluir um registro parâmetros de query
GET /fwmodel/Perfis/{pk} incluir um registro parâmetros de query
PUT /fwmodel/Perfis/{pk} incluir um registro body
DELETE /fwmodel/Perfis/{pk} incluir um registro nenhum

Estas são exatamente as mesmas operações que foram feitas na parte anterior, contudo não foi feita a criação de uma classe Rest para responder a estas requisições e sim utilizado um modelo mvc para lidar com o cadastro na sua forma padrão.

Estes endpoints e métodos respondem por padrão como Content-Type: application/json, sendo possível também receber no formato application/xml e para isso faça a requisição informando no header a chave Accept: application/xml; charset=utf-8.

Os exemplos de como usar os endpoints estão na coleção do postman no repositório.

Detalhes da api

A principal diferença para o serviço construído antes são as novas possibilidades que a publicação do padrão permite.

Na listagem dos itens é possível utilizar parâmetros de query que otimizam a busca permitindo recuperar somente os campos desejados e também controlar a paginação do itens.

  • paginação: combinando as propriedades count e startindex é possível fazer a paginação, um exemplo é a expressão /fwmodel/zmba010?count=20&startindex=2 que traria os registros de 21 a 40 conforme a ordem usada no modelo (normalmente a ordem de índice 1).
  • filtragem: com a propriedade filter é possível determinar uma expressão que irá restringir o resultado, como filter=ZT0_ADMIN = 1.
  • restrição de campos: com a propriedade fields é possível reduzir a quantidade de campos retornados, de forma a otimizar o tempo de resposta e ocupação de banda na rede, a expressão fields=ZT0_USRID,ZT0_NOME faria retornar somente os campos ZT0_USRID e ZT0_NOME.

Ter estas funcionalidades somente com a construção do modelo de dados MVC é um ganho imenso e portanto, no advento de não ter muito tempo para desenvolver uma api ou não querer deixar a api muito simples (como a da parte anterior), publicar um modelo é uma excelente saída. A desvantagem está no fato dos nomes dos campos serem as propriedades e com isso obrigar os clientes das apis lidarem com coisas que podem não fazer sentido nenhum para a aplicação cliente.

O modelo avançado

Nessa documentação já citada existe um recurso não utilizado na publicação do modelo para Perfis.
A opção RESOURCE OBJECT <objeto> permite determinar qual a classe fará uma parte da interpretação dos comandos entre o modelo (que possui os dados) e o fwmodel (que responde à requisição).
Tendo o controle dessa camada intermediária é possível implementar mais parâmetros de query e estender comportamentos, como permitir a definição de ordem dos dados na listagem geral que não é permitida por padrão.
Na documentação tem o fonte FWRestModelObject.prx com uma implementação bem similar a do padrão e um exemplo com a implementação simulada para um serviço de filiais.

Conclusão

Este é um tópico em que é importante utilizar a coleção do postman e os endpoints para ver as coisas acontecerem no sistema.
Muito é oferecido somente com a publicação do modelo e cadastros simples são bem atendidas somente com isso.
Não será feito uso deste formato de api no microblog usando o Protheus e este formato foi demonstrado aqui para deixar explícita uma das possibilidades.
A próxima publicação será sobre usar o modelo MVC para lidar com as operações de Criação, Atualização, Exclusão e Leitura no banco de dados ao invés de fazer estas operações diretamente com Reclock ou Insert.

Top comments (0)