Obtener datos JSON de servicios REST externos

Completado

En las unidades anteriores hemos visto cómo se recupera un resultado como texto; sin embargo, se trataba en realidad de un documento JSON. Dado que AL cuenta con compatibilidad integrada con los tipos JSON, puede modificar su solución para que funcione con un documento JSON.

Antes de poder trabajar con un documento JSON, primero debe analizar el valor de texto descargado en un JsonToken. El tipo de datos JsonToken es la clase base de todos los demás tipos de datos JSON. Por tanto, voy a usar la función ReadFrom del tipo de datos JsonToken para leer y analizar la entrada como un documento JSON. Esta función devuelve un valor booleano, lo que indica que la entrada era una estructura JSON válida.

El siguiente código de ejemplo muestra cómo el valor de la variable ResponseString se analiza como un JsonToken. Los datos se han recuperado de la siguiente opción.

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

En el siguiente ejemplo de código se muestra la respuesta de JSON para un usuario con el número cinco.

{
  "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 función ReadFrom se utiliza para analizar el texto de respuesta en un documento JSON. Tal y como se muestra en el ejemplo de respuesta anterior, el documento JSON no es una matriz sino un JsonObject con algunas claves y valores. Por tanto, primero debe probar que el JsonToken es un JsonObject y luego convertirlo con la función AsObject en un tipo de datos JsonObject. En un tipo de datos JsonObject, puede usar la función Get para recuperar un valor basado en la clave. En este ejemplo, obtendrá el valor de la clave de nombre, que de nuevo da como resultado un nuevo JsonToken. Tal y como se muestra en el ejemplo de respuesta anterior, el valor de la clave de nombre es el nivel más bajo en el objeto JSON, que se denomina tipo de datos JsonValue.

Este JsonToken se convertirá en un JsonValue. El contenido es de tipo Texto, por lo que debe convertir JsonValue como un valor de texto con la función 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('The call to the web service failed.');

    if not ResponseMessage.IsSuccessStatusCode() then
        Error('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('Invalid JSON document.');

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

    JObject := Jtoken.AsObject();

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

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

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

Los tipos de datos JSON y HTTP le permiten concatenar varias funciones en una línea de código. En lugar de definir una variable adicional con un tipo de datos JsonValue y asignar el Jtoken.AsValue a dicha variable, puede completar esta acción en una implementación.

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

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

En el siguiente ejemplo se muestra cómo puede crear su propio JsonObject para luego enviarlo mediante HttpClient a un servicio REST. Puedes usar la función Add en el tipo de datos JsonObject para agregar nuevos pares de claves o valores. El uso de la función WriteTo da como resultado la serialización de JsonObject en un valor de texto.

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('The call to the web service failed.');

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

    ResponseMessage.Content().ReadAs(ResponseString);

    Message(ResponseString);
end;