PHSYS API
Índice
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>;