Portals Web Api - (Part 1)

Portals Web Api

Portals API Security

Portals Web API ha sido una característica que toda persona de Portals ha estado pidiendo a Microsoft que se desarrolle y, finalmente, tenemos algo de luz sobre esta. Este desarrollo está (en el momento de escribir este post) en pre-release, asi que es posible que cambie. Sin embargo, podemos jugar con esta y es increíble.

Sobre qué es este post?

Voy a hablar sobre como crear Portals Web API y realizaremos Create and Update, descubriendo que sucede si realizamos algunos errores. Al mismo tiempo, os voy a ir dando consejos para la Cache del Portal y una para el AdBlock.

Punto de partida

He estado jugando con Portals desde Enero del 2018, cuando empecé con un proyecto que requería mucho Portals y al mismo tiempo estaba tan limitado que teniamos que hacer unos parches para solucionar todos los problemas que la API podría haber solucionado al instante. En ese momento, no tenia el mismo conocimiento con el que parto ahora, por ejemplo, empezamos haciendo “HTTPS GET” desde las ODATA Entity Endpoints (lo cual no recomiendo), y que al final movimos al estilo de FetchXML. En algún momento pondré un post sobre esto. Lo peor para mi, fue como actualizar o realizar cosas en segundo plano, tema workflows, acciones…

Si has usado alguna vez Portals antes, probablemente te sientas tan identificado con mi sentimiento de ese momento.

Y entonces, había otro problema, la Cache del Portal. Has tenido problemas con la Caché antes? Estoy seguro de ello, y adivino que tienes tu navegador favorito con la url de: …powerappsportals.com/_services/about para refrescar la Caché cada vez que realizas un cambio en el código. En el caso de que tengas algunos problemas con esto, te daré unos pequeños consejos, incluso aunque este post no fuera para eso, pero es Black Friday, así que, por qué no? Why not Gif

  1. La Cache del navegador y del Portals son diferentes.
  2. La caché del Portal se puede refrescar manualmente desde …powerappsportals.com/_services/about
  3. No puedes refrescar la Caché de otras personas.
  4. La Caché del Portals se refresca cada 15 mintuos y no puedes actualizarlo.

Y he aquí EL consejo.

  1. La caché del Portal se refresca si realizas alguna actualización a un entity form..

Eso es cierto, si no realizas nada y haces un submit de un formulario de entidad, tu página se refrescará y con esta, la Caché del Portals. Ese era el truco que Microsoft nos dió en su momento. Así que bueno, por qué soy tan pesado con eso de la Caché del Portals, blah blah blah? Porque la Web API del Portals que voy a explicar, no se refresca, así que no vas a ver los cambios en tiempo real, a menos que tengas un FetchXML y obtengas esos cambios (Es lo que vamos a hacer) Antes de que vayamos profundamente a los detalles, os dejaré la documentación sobre como crear un nuevo Power Apps Portals, siempre es bueno tenerla al lado tuya:

Crea tu Portal

Portals Web Api

Lo primero de todo, vayamos a la documentación donde todo está explicado y probablemente aprendamos lo mismo que aqui pero de un modo más aburrido y sin GIFs.

Portals Web Api Overview

Bien, primero de todo, deberías de tener tu Portals actualizado. ¿Por qué? Bueno, el primer item de la documentación es y lo voy a copiar: “La versión de tu portal debe ser 9.2.6.41 o posterior para que esta característica funcione.” Y la segunda? Bueno, algo que ya sabíamos, está en Preview. Desde este punto, vamos a configurar la Web API del Portal, asi que ahora viene lo bueno.

Why not Gif

Primer paso

Solamente para que lo sepas antes de empezar, vamos a crear un contacto con el rol de admin para probar todas las cosas y poder refrescar la caché cuando lo necesitemos. Vayamos a la configuración / site settings del Portals.

Aquí es donde vamos a habilitar la Web API para nuestra entidad. Iré a la entidad de cuenta y vamos a comprobar algunos ejemplos de como hacerlo. Para crear la API de una cuenta vamos a crear dos configuraciones:

  1. FPara habilitar la APi en la entidad del Portals.
    • Name: Webapi/account/enabled
    • Value: True
  2. Para habilitar los campos de la entidad a actualizar
    • Name: Webapi/account/fields
    • Value: address1_city,description

🔥 Un pequeño stop aquí, ya que quiero que compruebes que puedes poner aquí los campos a actualizar / crear. Si quieres todos los campos solemente tienes que poner un * y ya está. Iremos a y veremos que pasa si quitamos uno o lo ponemos y no se encuentra. Vamos a tener el misterio hasta el final.

Site settings

Segundo paso

Vamos a necesitar crear los Entity Permissions /Permisos de entidad para la entidad a modificar. Aquí necesitamos poner los permisos para la entidad Cuenta, así que hagamos eso. En este ejemplo, vamos a poner el scope a organización, probablemente tengas que poner otro, quien sabe. Entity permissions

Añade tu rol aquí, yo pondré el de admin.

Así que ahora todo está preparado en nuestro entorno, voy a realizar un refresco de la Caché para empezar con el código.

Si quieres algo de referencia de los documentos, visita esta url:

Portals Web Api Operations

Vas a necesitar algo de Javascript para realizar algunas acciones más rápido. Hay un código que Microsoft nos ha proporcionado amablemente y del que nos ayudaremos. En mi Header, voy a poner lo siguiente:

$(document).ready(function() {
    (function(utilities, $) {
        function getParameterByName(name) {
            var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
            return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
        }

        function safeAjax(ajaxOptions) {

            var deferredAjax = $.Deferred();

            shell.getTokenDeferred().done(function(token) {

                // add headers for AJAX
                if (!ajaxOptions.headers) {

                    $.extend(ajaxOptions, {

                        headers: {

                            "__RequestVerificationToken": token
                        }
                    });
                } else {

                    ajaxOptions.headers["__RequestVerificationToken"] = token;
                }
                $.ajax(ajaxOptions)
                    .done(function(data, textStatus, jqXHR) {

                        validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);
                    }).fail(deferredAjax.reject); //AJAX
            }).fail(function() {

                deferredAjax.rejectWith(this, arguments); // on token failure pass the token AJAX and args
            });

            return deferredAjax.promise();
        }
        utilities.safeAjax = safeAjax;
        utilities.getParameterByName = getParameterByName;
    })(window.utilities = window.utilities || {}, jQuery)
})

⭐ Por qué he hecho esto? Es una opinión personal, pero me gusta tener estas utilizades en el header para después reutilizarlas donde sea, ya que van a ser usadas a través de muchas páginas web. Dejaré por aquí el código de getParameterByName para obtener el parámetro de una URL (válido para IE). Para poder usarlo solamente tienes que escribir:

var myid = utilities.getParameterByName("id")
or
utilities.safeAjax() ...

Ahora crearemos nuestro WebTemplate /Plantilla Web para realizar el FetchXML y mostrar los resultados.

{% fetchxml Axazure %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
  <entity name="account">
    <attribute name="name" />
    <attribute name="description" />
    <attribute name="telephone1" />
    <attribute name="accountid" />
    <attribute name="address1_city" />
    <order attribute="name" descending="false" />
    <filter type="and">
      <condition attribute="name" operator="eq" value="Axazure" />
    </filter>
  </entity>
</fetch>
{% endfetchxml %}
{% for item in Axazure.results.entities %}
Name: {{item.name}}
Description: {{item.description}}
Telephone: {{item.telephone1}}
City: {{item.address1_city}}
{% endfor %}

En nuestra página, vayamos dentro de la Content Page. He creado una llamada PortalsApi.

🔥 Como sabes, la Content Page es la que se necesita para actualizar el HTML, CSS y Javascript, no lo actualices en la página de general.

💰 Si tienes problemas de carga de páginas web, deshabilita el Adblock.

Dentro del HTML pon esto:

{% include 'FetchXMLMyAccount' %}
<div>
    <div class="form-group">
        <label for="name">City</label>
        <input type="text" class="form-control" id="city" placeholder="City">
    </div>
    <div class="form-group">
        <label for="description">Description</label>
        <input type="text" class="form-control" id="description" placeholder="Description">
    </div>
    <div class="form-group">
        <label for="telephone">Telephone</label>
        <input type="text" class="form-control" id="telephone" placeholder="600000000">
    </div>
</div>
<div>
    <button type="button" class="btn btn-primary" onclick="OnClickUpdate()"> Perform Web API Update</button>
    <button type="button" class="btn btn-primary" onclick="OnClickCreate()"> Perform Web API Create</button>
</div>

y dentro del Javascript escribiremos: — Vais a ver que utilizo un GUID a pelo, pero es para ir más rápido, usad las cosas bien con los parámetros.


function OnClickUpdate() {
    var accountid = "f3c2d607-f830-eb11-a813-002248006bf5";
    var jsonObject = {
        "address1_city": $("#city").val(),
        "description": $("#description").val()
    }
    UpdateMyEntity("accounts",accountid, jsonObject);
}

function OnClickCreate() {
    var jsonObject = {
        "address1_city": $("#city").val(),
        "description": $("#description").val()
    }
    CreateMyEntity("accounts", jsonObject);
}

function UpdateMyEntity(entitynameplural, guid,jsonobject) {
    utilities.safeAjax({
        type:"PATCH",
        url:"/_api/" + entitynameplural + "(" + guid + ")",
        contentType: "application/json",
        data: JSON.stringify(jsonobject),
        success: function(result) {
            window.location.reload()
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) { 
            alert(XMLHttpRequest.responseJSON.error.message)
        }  
    })
}

function CreateMyEntity(entitynameplural,jsonobject) {
    utilities.safeAjax({
        type: "POST",
        url: "/_api/" + entitynameplural,
        contentType: "application/json",
        data: JSON.stringify(jsonobject),
        success: function (res, status, xhr) {
            alert("The id created is: " + xhr.getResponseHeader("entityid"));
        }, error: function(XMLHttpRequest, textStatus, errorThrown) { 
            alert(XMLHttpRequest.responseJSON.error.message)
        }
    });
}

Ahora, veamos que sucede si realizo un onClick en el botón.

🔑 He puesto el reload dentro de la página para que la cargue así el FetchXML.

Site Setting para Update Description and City

Good update GIF

Wohoo! Funciona! Ahora, vamos a quitar la ciudad de la configuración del campo. Actualizaremos de nuevo el mismo registro como antes, ahora debería fallarnos. Site Setting for Update

Description

Error update

Error update GIF

Ahora, crearemos con la ciudad y descripción.

Site Setting para Creación

Description

Error creation

Error create GIF

Así que falla de nuevo! Hagamos otra cosa, pongamos de nuesto la Site Setting the address1_city

Site Setting para Creation

Description

Good update GIF

Funciona” Asi que podemos crear la entidad con los campos que has puesto en las Site Settings, si no, fallará.

Con eso dicho, creo que es momento para que juegues con ello y lo compruebes.

Conclusión

Como has visto, es una gran gran gran mejora para toda la gente que usa Portals, Creo que habrá muchos cambios para bien que vendrán a resolver problemas que tuvimos en el pasado, como también lo es la Caché del Portal. Por el momento, juguemos con esto y disfruta de la transición que hace Microsoft para mejorar cosas. Hazme saber si tienes alguna pregunta o sugerencia. Si tienes alguna pregunta que hacerme, mándame un email a me@victorsolaya.com.


Únete a la newsletter