- Criado por Rafael Cesar Borges, última alteração por Ieda Ferreira Alves Flock em 09 dez, 2019
OBJETIVO
Utilizar um método único que realize várias ações na mesma requisição enviando um JSONARRAY.
Ex.: Em um único POST efetuar varias inserções de registros;
Exemplo de utilização do Array
Para melhor explicação do assunto, montamos um exemplo para o endpoint que cria os atalhos de execução e evoluímos para receber um JsonArray de atalhos a serem criados;
Como era o código
Recebendo somente JsonObject:
Clique para visualizar o conteúdo
Codigo original
/*------------------------------------------------------------------------------ Purpose: Inclui um atalho Local Notes: ------------------------------------------------------------------------------*/ PROCEDURE upsertLocalShortcut: DEFINE INPUT PARAMETER jsonInput AS JsonObject NO-UNDO. DEFINE INPUT PARAMETER isUpdate AS LOGICAL NO-UNDO. DEFINE VARIABLE idxShortcut AS INTEGER NO-UNDO. DEFINE VARIABLE payload AS JsonObject NO-UNDO. ASSIGN payload = jsonInput:GetJsonObject("payload"). /* inicio das validações e instruções */ /* Valida os campos obrigatorios */ RUN validateLocalRequiredFields IN THIS-PROCEDURE (INPUT payload). IF NOT VALID-HANDLE(hExecutionShortcutRepository) THEN RUN btb/properties/infrastructure/domain/ExecutionShortcutRepository.p PERSISTENT SET hExecutionShortcutRepository. ASSIGN idxShortcut = getIdxShortcut(jsonInput, isUpdate). /* Validacoes somente para update */ IF isUpdate THEN DO: /* Valida se existe o registro no banco de dados */ RUN validateIndex IN THIS-PROCEDURE (INPUT idxShortcut). /* Valida o tipo do atalho se foi alterado */ RUN validateTypeShortcut IN THIS-PROCEDURE (INPUT idxShortcut, INPUT {&LOCAL_ACCESS}). END. /* Valida a descricao do atalho */ RUN validateDescriptionShortcut IN THIS-PROCEDURE ( INPUT idxShortcut, INPUT JsonAPIUtils:getPropertyJsonObject(payload, "description") ). RUN setDefaultShortcut IN THIS-PROCEDURE ( INPUT idxShortcut, INPUT JsonAPIUtils:getPropertyJsonObject(payload, "description") ). RUN upsertLocalShortcut IN hExecutionShortcutRepository (INPUT payload, INPUT STRING(idxShortcut)). /* Fim das validações e instruções */ FINALLY: DELETE PROCEDURE hExecutionShortcutRepository NO-ERROR. END FINALLY. END PROCEDURE.
Após a implementação da técnica
Agora está preparado para receber JsonObject e JsonArray:
Clique para visualizar o conteúdo
Codigo Alterado
/*------------------------------------------------------------------------------ Purpose: Inclui um atalho Local Notes: ------------------------------------------------------------------------------*/ PROCEDURE upsertLocalShortcut: DEFINE INPUT PARAMETER jsonInput AS JsonObject NO-UNDO. DEFINE INPUT PARAMETER isUpdate AS LOGICAL NO-UNDO. DEFINE VARIABLE idxShortcut AS INTEGER NO-UNDO. DEFINE VARIABLE payload AS JsonObject NO-UNDO. DEFINE VARIABLE payloadArray AS JsonArray NO-UNDO. DEFINE VARIABLE iCountPayload AS INTEGER NO-UNDO. DEFINE VARIABLE iPayloadLength AS INTEGER NO-UNDO. ASSIGN iPayloadLength = CAST(jsonInput:getJSONArray("payload"), "JSONArray"):LENGTH NO-ERROR. payloadArray = NEW JsonArray(). ASSIGN payloadArray = jsonInput:getJSONArray("payload") NO-ERROR. IF payloadArray:LENGTH = 0 THEN do: // caso o tamanho seja zero payload = CAST(jsonInput:getJSONObject("payload"), "JSONObject") NO-ERROR. //atribui object payloadArray:ADD(payload). //adiciona ao array END. iPayloadLength = payloadArray:LENGTH. DO iCountPayload = 1 TO iPayloadLength: ASSIGN payload = payloadArray:getJSONObject(iCountPayload) NO-ERROR. /* inicio das validações e instruções */ /* Valida os campos obrigatorios */ RUN validateLocalRequiredFields IN THIS-PROCEDURE (INPUT payload). IF NOT VALID-HANDLE(hExecutionShortcutRepository) THEN RUN btb/properties/infrastructure/domain/ExecutionShortcutRepository.p PERSISTENT SET hExecutionShortcutRepository. ASSIGN idxShortcut = getIdxShortcut(jsonInput, isUpdate). /* Validacoes somente para update */ IF isUpdate THEN DO: /* Valida se existe o registro no banco de dados */ RUN validateIndex IN THIS-PROCEDURE (INPUT idxShortcut). /* Valida o tipo do atalho se foi alterado */ RUN validateTypeShortcut IN THIS-PROCEDURE (INPUT idxShortcut, INPUT {&LOCAL_ACCESS}). END. /* Valida a descricao do atalho */ RUN validateDescriptionShortcut IN THIS-PROCEDURE ( INPUT idxShortcut, INPUT JsonAPIUtils:getPropertyJsonObject(payload, "description") ). RUN setDefaultShortcut IN THIS-PROCEDURE ( INPUT idxShortcut, INPUT JsonAPIUtils:getPropertyJsonObject(payload, "description") ). RUN upsertLocalShortcut IN hExecutionShortcutRepository (INPUT payload, INPUT STRING(idxShortcut)). /* Fim das validações e instruções */ END. FINALLY: DELETE PROCEDURE hExecutionShortcutRepository NO-ERROR. END FINALLY. END PROCEDURE.
Documentação da Técnica utilizada
Código com comentários para auxiliar no desenvolvimento:
Clique para visualizar o conteúdo
Tecnica
//Opção 1: DEFINE VARIABLE payloadArray AS JsonArray NO-UNDO. DEFINE VARIABLE iCountPayload AS INTEGER NO-UNDO. DEFINE VARIABLE iPayloadLength AS INTEGER NO-UNDO. ASSIGN iPayloadLength = CAST(jsonInput:getJSONArray("payload"), "JSONArray"):LENGTH NO-ERROR. //Conta o tamanho do payload para identificar se é um object ou array / NO-ERROR para manter a compatibilidade com object /Cast para ler o json e contar o tamanho do payload (Se é array ou object) payloadArray = NEW JsonArray(). // Cria um JsonArray vazio para receber o array de objetos vindo do payload ASSIGN payloadArray = jsonInput:getJSONArray("payload") NO-ERROR. // Pega o array de objetos (Payload Array) e transforma no JsonArray IF payloadArray:LENGTH = 0 THEN do: // caso o tamanho seja zero, significa que é um object payload = CAST(jsonInput:getJSONObject("payload"), "JSONObject") NO-ERROR. //Se entrou nesta condição significa que é um array payloadArray:ADD(payload). //adiciona o object ao array END. iPayloadLength = payloadArray:LENGTH. //Efetua novamente a leitura do payload para confirmar se é um object ou Array - Se for array o tamanho do mesmo será utilizado para saber quantas vezes o bloco deve rodar para resgatar todos os objects do array DO iCountPayload = 1 TO iPayloadLength: // Bloco de repetição para varrer o object ate o ultimo object do array ASSIGN payload = payloadArray:getJSONObject(iCountPayload) NO-ERROR. // A cada execução um object do array é executado sendo atribuido ao payload object para não impactar nas proximas execuções // inicio do trecho de código de instruções e validações // Fim do trecho de código de instruções e validações END. // Fim do bloco de repetição //Fim Opção 1. //Opção 2 DEFINE VARIABLE payloadArray AS JsonArray NO-UNDO. DEFINE VARIABLE iCountPayload AS INTEGER NO-UNDO. DEFINE VARIABLE iPayloadLength AS INTEGER NO-UNDO. ASSIGN iPayloadLength = CAST(jsonInput:getJSONArray("payload"), "JSONArray"):LENGTH NO-ERROR. // Conta o tamanho do payload para identificar se é um object ou array / NO-ERROR para manter a compatibilidade com object /Cast para ler o json e contar o tamanho do payload (Se é array ou object) IF iPayloadLength >= 1 THEN // Se for maior que zero significa que é um array ASSIGN payloadArray = jsonInput:getJSONArray("payload"). //Adiciona o payload array em um objeto array ELSE ASSIGN payload = jsonInput:GetJsonObject("payload") //Adiciona um object(payload) em um object somente com o payload iPayloadLength = 1. // Como é um object, alimentamos o tamanho do array para passar no bloco abaixo DO iCountPayload = 1 TO iPayloadLength: ASSIGN payload = payloadArray:getJSONObject(iCountPayload) NO-ERROR. //Transfere para o object cada object do array e efetua a execução / NO-ERROR para manter compatilidade de código para JsonArray e jsonObject // inicio do trecho de código de instruções e validações // Fim do trecho de código de instruções e validações END.//Fim do bloco de repetição //Fim Opção 2
Testes no desenvolvimento
Usando o postman e enviando no body da requisição os seguintes conteúdos (Object e Array):
Clique para visualizar o conteúdo
Caso não tenha conhecimento sobre o funcionamento e utilização do postman, dê uma olhadinha na documentação Guia de Utilização do Postman
Tecnica
No formato array: [ { "idxShortcut": -1, "localPathPF": "c:\\teste\\pf.pf", "description": "c:\\teste1\\", "localPathP": "c:\\teste\\p.p", "type": "1", "localPathINI": "c:\\teste\\ini.ini" }, { "idxShortcut": -1, "localPathPF": "c:\\teste\\pf.pf", "description": "c:\\teste1B\\", "localPathP": "c:\\teste\\p.p", "type": "1", "localPathINI": "c:\\teste\\ini.ini" } ] No formato array com uma posição: [ { "idxShortcut": -1, "localPathPF": "c:\\teste\\pf.pf", "description": "c:\\teste1\\", "localPathP": "c:\\teste\\p.p", "type": "1", "localPathINI": "c:\\teste\\ini.ini" } ] No formato Object: { "idxShortcut": -1, "localPathPF": "c:\\teste\\pf.pf", "description": "c:\\teste1\\", "localPathP": "c:\\teste\\p.p", "type": "1", "localPathINI": "c:\\teste\\ini.ini" }
Visão Geral
Import HTML Content
Conteúdo das Ferramentas
Tarefas