Come ottenere dati JSON da servizi REST esterni

Completato

In precedenza, si è visto il modo in cui un risultato viene recuperato come testo; tuttavia, si trattava di un documento JSON. Poiché AL ha il supporto integrato per i tipi JSON, è possibile modificare la soluzione perché funzioni con un documento JSON.

Prima di poter lavorare con un documento JSON, è necessario analizzare il valore di testo scaricato in un JsonToken. Il tipo di dati JsonToken è la classe base per tutti gli altri tipi di dati JSON. Pertanto, si utilizza la funzione ReadFrom sul tipo di dati JsonToken per leggere e analizzare l'input come documento JSON. Questa funzione restituisce un valore booleano, indicante che l'input era una struttura JSON valida.

L'esempio di codice seguente mostra il modo in cui il valore della variabile ResponseString viene analizzato come JsonToken. I dati sono stati recuperati da quanto segue.

https://jsonplaceholder.typicode.com/users/<number>

La risposta JSON per un utente con numero cinque è illustrata nell'esempio di codice seguente.

{
  "id": 5,
  "name": "Chelsey Dietrich",
  "username": "Kamren",
  "email": "Lucio_Hettinger@annie.ca",
  "address": {
    "street": "Skiles Walks",
    "suite": "Suite 351",
    "city": "Roscoeview",
    "zipcode": "33263",
    "geo": {
      "lat": "-31.8129",
      "lng": "62.5342"
    }
  },
  "phone": "(254)954-1289",
  "website": "demarco.info",
  "company": {
    "name": "Keebler LLC",
    "catchPhrase": "User-centric fault-tolerant solution",
    "bs": "revolutionize end-to-end systems"
  }
}

La funzione ReadFrom viene utilizzata per analizzare il testo di risposta in un documento JSON. Come mostrato nell'esempio di risposta precedente, il documento JSON non è un array ma un JsonObject con chiavi e valori. Pertanto, si dovrebbe prima verificare che il JsonToken sia un JsonObject e convertirlo poi con la funzione AsObject in un tipo di dati JsonObject. In un tipo di dati JsonObject, è possibile usare la funzione Get per recuperare un valore in base alla chiave. In questo esempio, si ottiene il valore per la chiave del nome, che si traduce ancora in un nuovo JsonToken. Come mostrato nell'esempio di risposta precedente, il valore per la chiave del nome è il livello più basso nell'oggetto JSON, chiamato tipo di dati JsonValue.

Questo JsonToken verrà convertito in un JsonValue. Il contenuto è di tipo Text, quindi è necessario convertire JsonValue come valore di testo con la funzione AsText.

procedure GetUserInformation(UserNumber: Integer)
var
    Client: HttpClient;
    ResponseMessage: HttpResponseMessage;
    ResponseString: Text;
    Jtoken: JsonToken;
    Jtoken2: JsonToken;
    JObject: JsonObject;
begin
    if not Client.Get(StrSubstNo('https://jsonplaceholder.typicode.com/users/%1',
                      UserNumber), ResponseMessage) then
        Error(ErrorInfo.Create('The call to the web service failed.'));

    if not ResponseMessage.IsSuccessStatusCode() then
        Error(ErrorInfo.Create('The web service returned an error message:\\' +
              'Status code: ' + Format(ResponseMessage.HttpStatusCode()) +
              'Description: ' + ResponseMessage.ReasonPhrase()));

    ResponseMessage.Content().ReadAs(ResponseString);

    if not Jtoken.ReadFrom(ResponseString) then
        Error(ErrorInfo.Create('Invalid JSON document.'));

    if not Jtoken.IsObject() then
        Error(ErrorInfo.Create('Expected a JSON object.'));

    JObject := Jtoken.AsObject();

    if not JObject.Get('name', Jtoken2) then
        Error(ErrorInfo.Create('Value for key name not found.'));

    if not Jtoken2.IsValue then 
        Error(ErrorInfo.Create('Expected a JSON value.'));     

    Message(Jtoken2.AsValue().AsText());
end;

I tipi di dati JSON e HTTP consentono di concatenare più funzioni in un'unica riga di codice. Anziché definire una variabile aggiuntiva con un tipo di dati JsonValue e assegnare il Jtoken.AsValue a quella variabile, è possibile completare questa azione in un'unica implementazione.

var
    Jtoken: JsonToken;
    Jvalue: JsonValue;
begin  
    Jvalue := Jtoken.AsValue();
    Message(Jvalue.AsText());

    // You can execute this in one line
    Message(Jtoken.AsValue().AsText());
end;

L'esempio seguente mostra come creare il proprio JsonObject per inviarlo in un secondo momento utilizzando HttpClient a un servizio REST. È possibile usare la funzione Add sul tipo di dati JsonObject per aggiungere nuove coppie chiave/valore. L'utilizzo della funzione WriteTo determina la serializzazione di JsonObject in un valore di testo.

procedure CreatePost()
var
    Client: HttpClient;
    Content: HttpContent;
    ResponseMessage: HttpResponseMessage;
    ResponseString: Text;
    JObject: JsonObject;
    JsonText: Text;
begin 

    JObject.Add('userId', 2);
    JObject.Add('id', 101);
    JObject.Add('title', 'Microsoft Dynamics 365 Business Central Post Test');
    JObject.Add('body', 'This is a MS Dynamics 365 Business Central Post Test');
    JObject.WriteTo(JsonText);

    Content.WriteFrom(JsonText);

    if not Client.Post('https://jsonplaceholder.typicode.com/posts', Content, 
                       ResponseMessage) then
        Error(ErrorInfo.Create('The call to the web service failed.'));

    if not ResponseMessage.IsSuccessStatusCode() then
        Error(ErrorInfo.Create('The web service returned an error message:\\' +
                'Status code: ' + Format(ResponseMessage.HttpStatusCode()) +
                'Description: ' + ResponseMessage.ReasonPhrase()));

    ResponseMessage.Content().ReadAs(ResponseString);

    Message(ResponseString);
end;