DEV Community

Josimar Junior
Josimar Junior

Posted on • Edited on

1

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.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more