Árvore de páginas


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:

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:

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:

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):

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"
}