REST API en SharePoint 2013 I: Consulta básica sobre listas

SharePoint 2010 introdujo el “Client Object Models”, que permitía a los desarrolladores interactuar con el modelo de objetos a través de clientes Web, como Silverlight, Javascript y el modelo del lado cliente de .NET a través del servicio _vti_bin/client.svc.

En SharePoint 2013 el servicio client.svc se ha mejorado con capacidades REST (Representational State Transfer), soportando acceso directo a los clientes REST y haciendo más sencillo el acceso al mismo, o lo que es lo mismo, se podrá acceder al modelo de objetos haciendo uso de cualquier tecnología que sea compatible con las solicitudes REST.

Para usar estas capacidades REST habrá que construir peticiones RESTful utilizando el protocolo OData (Open Data Protocol), y el servicio client.svc entregará la respuesta en Atom o JSON, dejando que el programador se encargue de procesar dicha respuesta.

SharePoint REST service architecture

REST nos va a permitir realizar operaciones CRUD (Create, Read, Update y Delete) sobre los objetos SharePoint (listas, elementos de listas, sitios…). Típicamente las operaciones de lectura serán peticiones HTTP de tipo GET, mientras que las de creación y actualización serán de tipo POST, PUT, MERGE y PATCH.

En esta primera parte vamos a hacer un ejemplo sencillo del uso de peticiones de lectura sobre listas de SharePoint, que son las construcciones más sencillas, puesto que las que van a realizar modificaciones sobre objetos SharePoint requieren realizar una obtención de los que SharePoint denomina “Form Digest”, pero eso lo veremos más adelante.

Sintaxis de la estructura de una URI REST

En el siguiente esquema se muestra cómo es la sintaxis que se utiliza para construir URIs para atacar al servicio. Aunque en el ejemplo vamos a utilizar Javascript en un Webpart para mostrar los resultados, se puede también introducir la consulta directamente en la barra de direcciones del navegador y comprobar los datos que devuelve:SharePoint REST request syntax

Por ejemplo, para consultar las listas de la web actual, bastaría con escribir en nuestra barra de direcciones del navegador lo siguiente:

http://sp2013/_api/lists

Y en el navegador veríamos la respuesta del servicio.

Visto un breve resumen, vamos a comenzar con un ejemplo. Vamos a crear un Webpart muy sencillo, que contenga un botón que lance una petición REST para obtener todas las listas de la web actual y las muestre en una tabla. Para ello comenzamos un proyecto de tipo Visual Web Part.

image

image

Vamos a ayudarnos de jQuery para realizar las consultas imageAjax, por lo tanto debemos descargarlo y añadirlo a nuestra solución. También vamos a crear un script Javascript para escribir todo nuestro código. Organizarlo como más os guste, pero tened en cuenta luego los enlaces desde Webpart a la hora de hacer las referencias a los mismos.

En el código del control que forma parte del Webpart vamos a añadir las referencias a los dos scripts y además un botón que sea en que llame a nuestra función de Javascript, y una zona para insertar la tabla con los resultados. Podría tener esta pinta:

image

Vamos a comenzar con el Javascript. Creamos nuestra función encargada de hacer la llamada al servicio:

function getCurrentSiteLists() {
console.log("getCurrentSiteLists");

$.ajax({
url: "/_api/lists",
type: "GET",
headers: { "accept": "application/json; odata=verbose" },
dataType: "json",
success: onGetCurrentSiteListsSuccess,
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
}
});
}

Atended a los parámetros. Por un lado vamos a indicar la url a la que vamos a atacar, que en este caso es una url relativa a nuestro sitio, seguido de /_api/lists, ya que vamos a pedir las listas del sitio actual. Por otro lado el tipo de petición, es un tipo GET, y el tipo de dato que vamos a obtener es JSON. Además como cabecera de la petición es obligatorio indicar “accept”:”application/json; odata=verbose”. Sin este último parámetro no podemos realizar la petición, porque nos devolverá un error la respuesta.


Ahora vamos a construir la función que va a encargarse de recoger la respuesta y construir la tabla que vuelque los datos en pantalla:


function onGetCurrentSiteListsSuccess(data) {
console.log("onGetCurrentSiteListsSuccess");

if (data.d) {
var items = [];

items.push("<table>");
items.push("<tr><td>List ID</td><td>Title</td></tr>");

$.each(data.d.results, function (key, val) {
items.push("<tr><td>" +
val.Id + "</td><td>" +
val.Title + "</td><td></tr>");
});

items.push("</table>");
$("#RestResults").html(items.join(""));
}
}

Vamos a mostrar una tabla con el Guid de la lista y su título. El resultado de pulsar el botón sería similar al siguiente:


image


Hasta aquí es posible que nos hayamos encontrado con algunos problemas. Si es así revisad los parámetros de la consulta al servicio REST. Si aún así sigue habiendo problemas, revisad el log de SharePoint. imageYo por ejemplo, debido a limitaciones de máquina obtuve un error de memoria. El servicio me devolvió un Internal Server Error, y mirando en el log de SharePoint pude ver que se trataba de que la memoria escaseaba. El detalle del error era el siguiente:


Application error when access /_vti_bin/client.svc, Error=Memory gates checking failed because the free memory (180297728 bytes) is less than 5% of total memory. As a result, the service will not be available for incoming requests. To resolve this, either reduce the load on the machine or adjust the value of minFreeMemoryPercentageToActivateService on the serviceHostingEnvironment config element.

at System.ServiceModel.Activation.ServiceMemoryGates.Check(Int32 minFreeMemoryPercentage, Boolean throwOnLowMemory, UInt64& availableMemoryBytes)

at System.ServiceModel.ServiceHostingEnvironment.HostingManager.CheckMemoryCloseIdleServices(EventTraceActivity eventTraceActivity)

at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity)

Y efectivamente, la memoria que quedaba libre era más bien poca.imageSolución, liberar memoria o asignar más a la máquina.




Una cosa que me ha gustado bastante del JSON devuelto ha sido que cuando queremos acceder a un atributo de un objeto que hemos pedido, y ese atributo es complejo, como por ejemplo, imagelos elementos que forman parte de la lista que estamos consultando, en el valor de ese atributo nos va a dar la url a la que tendríamos que atacar con REST para obtener dicha información. Esto se puede ver depurando el Javascript. Por ejemplo, obtenemos primero todas las listas del sitio en el objeto data.


Y depurando entramos en el detalle de cualquiera de las listas, y buscamos el atributo Items. Podremos ver que no salen directamente, y que en su lugar tenemos la url para realizar la siguiente consulta:


image


Por ejemplo, vamos a listar todos los atributos de la lista que seleccionemos. Para ello vamos a modificar el código Javascript, de tal forma que cuando hagamos clic en el Guid de la lista la tabla se alimente de esos valores. Vamos a consultar un atributo __metadata que tiene cada lista con la url a la que vamos a atacar con REST:


image


El atributo uri nos da la url que necesitamos, así que vamos a modificar cómo se presentan los datos de la primera consulta. Para ello, dentro del foreach vamos a construir un botón como el siguiente:


$.each(data.d.results, function (key, val) {
var metaUri = escape(val.__metadata.uri);
var linkDetails = "<button type='button' onclick=\"showListDetails('" + metaUri + "');\">" +
val.Id + "</button>";
items.push("<tr><td>" +
linkDetails + "</td><td>" +
val.Title + "</td><td></tr>");
});

Y creamos el código que lanzará la consulta REST:


function showListDetails(listUri) {
console.log("showListDetails");

$.ajax({
url: unescape(listUri),
type: "GET",
headers: { "accept": "application/json; odata=verbose" },
dataType: "json",
success: onShowListDetailsSuccess,
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
}
});
}

Y a continuación el código encargado de volcar los datos en la tabla:


function onShowListDetailsSuccess(data) {
console.log("onShowListDetailsSuccess");

if (data.d) {
var items = [];

items.push("<table>");
items.push("<tr><td>Attribute</td><td>Value</td></tr>");

$.each(data.d, function (key, val) {
items.push("<tr><td>" +
key + "</td><td>" +
val + "</td><td></tr>");
});

items.push("</table>");
$("#RestResults").html(items.join(""));
}
}

Así, cuando hagamos clic en el elemento de la lista, veremos todos los atributos junto con sus valores. El resultado sería similar al siguiente:


image


Como veis REST nos da la capacidad de realizar consultas del lado del cliente muy potentes, y podemos luego tratar y explotar los datos como nos convenga.


En esta caso hemos realizado sólo consultas de lectura. En el siguiente artículo veremos algún ejemplo de cómo realizar la creación de una lista y la diferencia que hay en la construcción de las peticiones REST.


Si queréis ampliar información, podéis hacer uso de los siguientes enlaces:


Programming using the SharePoint 2013 REST service


Using the SharePoint 2013 REST service

0 comentarios:

Publicar un comentario

SharePoint Between Racks © 2012
. Con la tecnología de Blogger.

¡Compártelo!


Estoy en LinkedIn!


Ve mi perfil en LinkedIn!