Cómo crear Apex SOAP Web Services y Apex REST Web Services en Sites públicos en Force.com

Site.com

Cuando necesitamos realizar integraciones de nuestras aplicaciones con nuestra plataforma de Force.com, y de esta forma poder acceder a los datos de Salesforce.com de la manera más sencilla posible, o necesitamos exponer nuestros métodos APEX de Force.com para poder desarrollar, por ejemplo, aplicaciones móviles, Force.com nos da la posibilidad de poder crear Servicios Web basados tanto en SOAP como en REST.

El acceso a estos Servicios Web desde nuestras aplicaciones externas se realiza mediante autenticación. La forma de autenticarnos con Salesforce es usando OAuth 2.0. Pero, ¿qué ocurre si nuestros Servicios Web los incluimos dentro de un Site público de Force.com? Pues que en este caso no es necesaria la autenticación. Por lo tanto centraré este post en explicar cómo podemos acceder a nuestros Servicios Web de Force.com de forma anónima, sin necesidad de autenticarnos.

Debemos tener muy presentes los permisos que concedemos al perfil del usuario invitado del Site en el que publicamos nuestros Servicios Web, ya que los datos serán accesibles de forma pública.

Antes de nada, daremos un pequeño repaso a la creación de Servicios Web basados en REST y en otro post posterior lo haré sobre los Servicios Web basados en SOAP. La forma de crear estos servicios en Force.com es mediante código APEX.

Servicios Web basados en REST

La API REST de Force.com permite integrar aplicaciones externas con Force.com utilizando métodos sencillos de HTTP, ya sea con formato XML o JSON, haciéndolo ideal para desarrollar aplicaciones móviles o clientes externos.

Gestionar datos usando Force.com REST API

Gestionar datos usando Force.com REST API

Force.com nos facilita seis anotaciones que nos permiten exponer una clase de Apex como un servicio REST:

  • @RestResource(urlMapping=’/TuUrl‘).  Se usa a nivel de clase y te permite exponer tu clase APEX como un recurso REST. El mapeo de la URL es case-sensitive, es decir, distingue mayúsculas y minúsculas. Para utilizar esta anotación tu clase APEX debe ser definida como global.
  • @HttpDelete. Se usa a nivel de método. Este método es invocado cuando se envía una petición HTTP DELETE. Para utilizar esta anotación tu método APEX deber ser definido como global.
  • @HttpGet. Se usa a nivel de método. Este método es invocado cuando se envía una petición HTTP GET. Para utilizar esta anotación tu método APEX deber ser definido como global.
  • @HttpPatch. Se usa a nivel de método. Este método es invocado cuando se envía una petición HTTP PATCH. Para utilizar esta anotación tu método APEX deber ser definido como global.
  • @HttpPost. Se usa a nivel de método. Este método es invocado cuando se envía una petición HTTP POST. Para utilizar esta anotación tu método APEX deber ser definido como global.
  • @HttpPut. Se usa a nivel de método. Este método es invocado cuando se envía una petición HTTP PUT. Para utilizar esta anotación tu método APEX deber ser definido como global.

Sólo puede existir una anotación de cada tipo en la clase APEX. Es decir, sólo podremos tener una anotación del tipo @HttPost, por ejemplo.

APEX REST soporta dos formatos: JSON y XML, y se debe indicar el tipo utilizado en la propiedad Content-Type de la cabecera HTTP. El formato JSON es el que se utiliza por defecto en el cuerpo de una petición (HttpRequest) o respuesta (HttpResponse). A modo de resumen debemos tener en cuenta las siguientes consideraciones:

  • Los objetos RestRequest (HttpRequest) y RestResponse (HttpResponse) están disponibles por defecto en los métodos APEX a través del objeto estático RestContext. Este ejemplo muestra cómo podemos acceder a estos objetos:
    RestRequest req = RestContext.request;
    RestResponse res = RestContext.response;
  • Si el método APEX utilizado no tiene parámetros,  APEX REST copia el cuerpo de la petición HTTP en la propiedad RestRequest.requestBody, de tipo Blob.
  • Si se han definido parámetros en el método APEX utilizado,  APEX REST intenta deserializar los datos y convertirlos en los parámetros.
  • APEX REST usa una lógica similar de serialización para las respuestas. Si el método APEX está definido para devolver un tipo determinado, APEX REST serializa el valor correspondiente y lo devuelve dentro de la propiedad RestResponse.responseBody.
  • Los métodos con anotaciones @HttpGet o @HttpDelete no deberían tener parámetros. Esto es debido a que las peticiones HTTP GET y DELETE carecen de cuerpo, por lo que no habría nada que deserializar.
  • APEX REST actualmente no soporta peticiones con el Content-Type del tipo multipart/form-data.

A continuación puedes ver un ejemplo de una clase APEX expuesta como servicio REST obtenido de aquí:

@RestResource(urlMapping='/Account/*')
global with sharing class MyRestResource {

    @HttpDelete
    global static void doDelete() {
        RestRequest req = RestContext.request;
        String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        Account account = [SELECT Id FROM Account WHERE Id = :accountId];
        delete account;
    }

    @HttpGet
    global static Account doGet() {
        RestRequest req = RestContext.request;
        String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = :accountId];
        return result;
    }

    @HttpPost
    global static String doPost(String name, String phone, String website) {
        Account account = new Account();
        account.Name = name;
        account.phone = phone;
        account.website = website;
        insert account;
        return account.Id;
    }
}

La url de acceso a nuestra clase APEX expuesta como servicio REST, utilizando autenticación OAuth 2.0, sería de la siguiente forma:

https://instance.salesforce.com/services/apexrest/urlMapping

Donde:

  • instance. Es el nombre de la instancia de nuestra organización.
  • urlMapping. Es la URL relativa de mapeo de nuestro servicio APEX REST.

Siguiendo este mismo ejemplo, si quisiéramos crear una cuenta nueva utilizando nuestro servicio REST, tendríamos que realizar una petición HTTP POST, con el Content-Type: application/json, a la url:

https://instance.salesforce.com/services/apexrest/Account

Y como cuerpo de la petición tendríamos que pasar el siguiente JSON:

{
  "name" : "José Luis ALmazán",
  "phone" : "690968879",
  "website" : "http://salesforceafondo.wordpress.com"
}

Como estamos realizando una petición POST, se ejecutaría el método APEX doPost() y Salesforce devolvería una cadena de texto con el Id de la cuenta que se acaba de crear:

"accountId"

Y básicamente ésta sería una pequeña introducción a los servicios APEX REST.

Todo esto está muy bien, pero como ya he dicho antes, resulta que en este ejemplo debemos utilizar autenticación OAuth 2.0 para poder acceder al servicio REST. Ahora pasaré a explicar qué debemos hacer para poder utilizar este mismo servicio REST de forma pública, sin necesidad de autenticación. Para ello, lo primero que debemos hacer es crearnos un Site o utilizar un Site que ya tengamos. Es muy importante indicar que Force.com Sites sólo está disponible para las ediciones: Developer, Enterprise y Unlimited.

Para crear un Site, siga los siguientes paso:

  1. Haga clic en Su nombre | Configuración | Desarrollos | Sitios -> Botón Nuevo.
  2. Cumplimente los campos necesarios y haga clic en el botón Guardar.
Crear Site

Crear Site

Ya tendríamos el Site creado. Para poder hacer público nuestro servicio REST en este Site, lo primero que necesitamos es conceder acceso al perfil del Site a la clase APEX de nuestro servicio REST, en el ejemplo anterior MyRestResource. Además, debemos conceder los permisos necesarios de lectura y/o escritura sobre los objetos implicados en nuestros métodos APEX REST. Para ello:

  1. Haga clic en Su nombre | Configuración | Desarrollos | Sitios.
  2. Haga clic en el nombre del sitio que desea controlar.
  3. Haga clic en Configuración de acceso público para abrir la página del perfil del sitio.
  4. Vaya hasta Acceso a clase de Apex activado y pulse sobre el botón Modificar para poder Activar la clase APEX correspondiente a nuestro servicio REST. Para aceptar los cambios pulse el botón Guardar.
  5. Si necesita conceder permisos a algún objeto (en el ejemplo anterior necesitaríamos conceder permisos de lectura/escritura sobre el objeto Cuentas), pulse sobre el botón Modificar (seguimos dentro de la Configuración de acceso público), vaya hasta los Permisos de objetos y seleccione los permisos necesarios. Para finalizar pulse sobre el botón Guardar.
Conceder permisos al perfil del Site

Conceder permisos al perfil del Site

Ya tendríamos publicado nuestro servicio APEX REST en nuestro Site, por lo que ya sería accesible de forma pública. En este caso, debemos es muy importante indicar que la url de acceso a nuestro servicio REST es diferente a la que indicábamos anteriormente, cuando el servicio REST requería autenticació. Al estar publicado dentro del Site, la url sería de la siguiente forma:

https://dominioForceCom/site/services/apexrest/urlMapping

Donde:

  • dominioForceCom. Es el nombre de nuestro dominio de Force.com en nuestra organización. En mi entorno de desarrollo, sería jlalmazan-developer-edition.na14.force.com.
  • site. Es el nombre de nuestro Site.
  • urlMapping. Es la URL relativa de mapeo de nuestro servicio APEX REST.

Y ya tendríamos nuestro servicio APEX REST accesible de forma pública.

Espero que os sirva de ayuda este post. Si os ha gustado, podéis seguir mi blog o seguirme en twitter.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s