PHSYS API

Revisão de 15h59min de 23 de julho de 2026 por Alex.vieira (discussão | contribs)

Introducao

Este exemplo mostra como configurar um unico endpoint de API para executar varios procedimentos internos, usando o campo MetodoScript no body da requisicao.

A proposta e ter um endpoint unico, por exemplo:

http://localhost:211/api/solicitacoes

e dentro do script, direcionar a execucao para:

  • Cadastrar
  • Consultar
  • Cancelar

Esse modelo e util quando os procedimentos pertencem ao mesmo contexto funcional e compartilham a mesma autenticacao e URL de integracao.

Modelo de Integracao Personalizado

No cadastro do endpoint no PHServerConf:

  • Modelo de integracao: Personalizado
  • Classe: script especifico
  • Procedimento: GetMetodo
  • Exige token: Sim (opcional, recomendado)

Com isso, toda requisicao ao endpoint passa pelo procedimento GetMetodo, que decide qual acao executar com base no body.

Cabecalhos Necessarios

  • Content-Type: application/json
  • Authorization: Bearer <access_token> (quando OAuth2 estiver habilitado)

Estrutura da Requisicao

URL:

http://<servidor>:<porta>/api/solicitacoes

Metodo HTTP:

POST

Body base:

{
  "MetodoScript": "Cadastrar | Consultar | Cancelar",
  "...": "demais campos conforme cada metodo"
}

Exemplo de Bodies

1) Cadastrar

{
  "MetodoScript": "Cadastrar",
  "Cliente": "2",
  "Solicitante": "2",
  "TiposSolicitacao": "3",
  "Requisito": "2",
  "Prioridade": "2",
  "DescricaoResumida": "Solicitacao de exemplo",
  "Descricao": "Descricao detalhada da solicitacao"
}

2) Consultar

{
  "MetodoScript": "Consultar",
  "SolicitacaoID": "150"
}

3) Cancelar

{
  "MetodoScript": "Cancelar",
  "SolicitacaoID": "150",
  "Motivo": "Solicitacao aberta em duplicidade"
}

Exemplo de Script

procedure GetMetodo;
var
  Metodo: String;
begin
  Metodo := UpperCase(ObterMetodoFromBody);

  if (Metodo = 'CADASTRAR') then
    Cadastrar
  else if (Metodo = 'CONSULTAR') then
    Consultar
  else if (Metodo = 'CANCELAR') then
    Cancelar
  else
    ErroValidacao('Processo invalido. Metodo informado: ' + Metodo);
end;

function ObterMetodoFromBody: String;
var
  Body: String;
  JsonObj: TPHJson;
begin
  Body := Trim(GetBody);

  if (Body = '') then
    ErroValidacao('Faltou informar o body da requisicao.');

  JsonObj := TPHJson.Create;
  try
    JsonObj.LerJson(Body);
    Result := Trim(JsonObj.ElementoDoNome('MetodoScript').Texto);
  finally
    JsonObj.Free;
  end;
end;

function MontarRetornoSucesso(const Detalhes: String): String;
begin
  Result :=
    '{' +
      '"status":"sucesso",' +
      '"detalhes":"' + Detalhes + '"' +
    '}';
end;

function MontarRetornoErro(const Detalhes: String): String;
begin
  Result :=
    '{' +
      '"status":"erro",' +
      '"detalhes":"' + Detalhes + '"' +
    '}';
end;

procedure Cadastrar;
var
  Body: String;
  JsonObj: TPHJson;
  SolicitacaoObj: TPHServerClass;
  Msg: String;
begin
  Body := Trim(GetBody);

  JsonObj := TPHJson.Create;
  try
    JsonObj.LerJson(Body);

    SolicitacaoObj := NewPHServerClass('SOLICITACOES');
    try
      IniciarTransacao;
      try
        SolicitacaoObj.NovoRegistro;
        SolicitacaoObj.CampoDoNome('PESSOA').AsLargeInt := StrToInt(JsonObj.ElementoDoNome('Cliente').Texto);
        SolicitacaoObj.CampoDoNome('SOLICITANTE').AsLargeInt := StrToInt(JsonObj.ElementoDoNome('Solicitante').Texto);
        SolicitacaoObj.CampoDoNome('TIPOSOLICITACAO').AsLargeInt := StrToInt(JsonObj.ElementoDoNome('TiposSolicitacao').Texto);
        SolicitacaoObj.CampoDoNome('REQUISITO').AsLargeInt := StrToInt(JsonObj.ElementoDoNome('Requisito').Texto);
        SolicitacaoObj.CampoDoNome('NIVELPRIORIDADE').AsLargeInt := StrToInt(JsonObj.ElementoDoNome('Prioridade').Texto);
        SolicitacaoObj.CampoDoNome('NOME').AsString := JsonObj.ElementoDoNome('DescricaoResumida').Texto;
        SolicitacaoObj.CampoDoNome('DESCRICAOPROBLEMA').AsString := JsonObj.ElementoDoNome('Descricao').Texto;
        SolicitacaoObj.Salvar;

        ConfirmarTransacao;
        Msg :=
          '{' +
            '"status":"sucesso",' +
            '"detalhes":"Solicitacao cadastrada.",' +
            '"SolicitacaoID":"' + IntToStr(SolicitacaoObj.CampoDoNome('ID').AsLargeInt) + '"' +
          '}';
      except
        CancelarTransacao;
        Msg := MontarRetornoErro('Erro ao cadastrar solicitacao: ' + ExceptionMessage);
      end;
    finally
      SolicitacaoObj.Free;
    end;
  finally
    JsonObj.Free;
  end;

  ParamByName('Result').AsString := Msg;
end;

procedure Consultar;
var
  Body: String;
  JsonObj: TPHJson;
  Q: TPHQuery;
  SolicitacaoID: String;
  Msg: String;
begin
  Body := Trim(GetBody);

  JsonObj := TPHJson.Create;
  try
    JsonObj.LerJson(Body);
    SolicitacaoID := JsonObj.ElementoDoNome('SolicitacaoID').Texto;

    Q := NewPHQuery;
    try
      Q.Add('SELECT ID, NOME, DESCRICAOPROBLEMA, SITUACAO ' +
            'FROM SOLICITACOES ' +
            'WHERE ID = :ID');
      Q.ParamByName('ID').AsLargeInt := StrToInt(SolicitacaoID);
      Q.Open;

      if Q.Vazia then
        Msg := MontarRetornoErro('Solicitacao nao encontrada.')
      else
        Msg :=
          '{' +
            '"status":"sucesso",' +
            '"Solicitacao":{' +
              '"ID":"' + Q.FieldByName('ID').AsString + '",' +
              '"NOME":"' + Q.FieldByName('NOME').AsString + '",' +
              '"DESCRICAO":"' + Q.FieldByName('DESCRICAOPROBLEMA').AsString + '",' +
              '"SITUACAO":"' + Q.FieldByName('SITUACAO').AsString + '"' +
            '}' +
          '}';
    finally
      Q.Free;
    end;
  finally
    JsonObj.Free;
  end;

  ParamByName('Result').AsString := Msg;
end;

procedure Cancelar;
var
  Body: String;
  JsonObj: TPHJson;
  SolicitacaoObj: TPHServerClass;
  Msg: String;
  SolicitacaoID: Int64;
begin
  Body := Trim(GetBody);

  JsonObj := TPHJson.Create;
  try
    JsonObj.LerJson(Body);
    SolicitacaoID := StrToInt(JsonObj.ElementoDoNome('SolicitacaoID').Texto);

    SolicitacaoObj := NewPHServerClass('SOLICITACOES');
    try
      IniciarTransacao;
      try
        SolicitacaoObj.CampoDoNome('ID').AsLargeInt := SolicitacaoID;
        SolicitacaoObj.LerRegistro;

        if (SolicitacaoObj.CampoDoNome('ID').AsLargeInt = 0) then
          ErroValidacao('Solicitacao nao encontrada para cancelamento.');

        SolicitacaoObj.CampoDoNome('SITUACAO').AsString := 'C';
        SolicitacaoObj.CampoDoNome('OBS').AsString := JsonObj.ElementoDoNome('Motivo').Texto;
        SolicitacaoObj.Salvar;

        ConfirmarTransacao;
        Msg := MontarRetornoSucesso('Solicitacao cancelada com sucesso.');
      except
        CancelarTransacao;
        Msg := MontarRetornoErro('Erro ao cancelar solicitacao: ' + ExceptionMessage);
      end;
    finally
      SolicitacaoObj.Free;
    end;
  finally
    JsonObj.Free;
  end;

  ParamByName('Result').AsString := Msg;
end;

begin
end.

Exemplo de Envio (cURL)

Cadastrar

curl -X POST "http://localhost:211/api/solicitacoes" ^
  -H "Content-Type: application/json" ^
  -H "Authorization: Bearer <access_token>" ^
  -d "{\"MetodoScript\":\"Cadastrar\",\"Cliente\":\"2\",\"Solicitante\":\"2\",\"TiposSolicitacao\":\"3\",\"Requisito\":\"2\",\"Prioridade\":\"2\",\"DescricaoResumida\":\"Solicitacao de exemplo\",\"Descricao\":\"Descricao detalhada\"}"

Consultar

curl -X POST "http://localhost:211/api/solicitacoes" ^
  -H "Content-Type: application/json" ^
  -H "Authorization: Bearer <access_token>" ^
  -d "{\"MetodoScript\":\"Consultar\",\"SolicitacaoID\":\"150\"}"

Cancelar

curl -X POST "http://localhost:211/api/solicitacoes" ^
  -H "Content-Type: application/json" ^
  -H "Authorization: Bearer <access_token>" ^
  -d "{\"MetodoScript\":\"Cancelar\",\"SolicitacaoID\":\"150\",\"Motivo\":\"Duplicidade\"}"

Resumo

Com esse padrao, um unico endpoint consegue atender varias operacoes de um mesmo dominio, mantendo:

  • Uma URL unica para integracao
  • Controle centralizado de autenticacao
  • Flexibilidade para evoluir os procedimentos no script

Para respostas personalizadas, utilize sempre:

ParamByName('Result').AsString := <texto ou JSON>;