Envíos etiquetados con ‘Rest’

Cliente REST Android

Junio 17th, 2010

Si quieres jugar haciendo operaciones REST con JSON en Android, y no tienes nada hecho, esto te puede servir de ayuda.

package packageName_00.PackageName_01;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.json.JSONObject;
import android.util.Log;

public class RestClient {

    public interface RequestCallback {
    	public void onError(Throwable exception);
    	public void onResponseReceived(HttpResponse response);
    }

    public static void doGet(final String url, final RequestCallback callback) {
    	Log.i("doGet", " - url: " + url);
    	final HttpClient httpClient = new DefaultHttpClient();
    	HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 10000);
    	Thread thread = new Thread(){
    		public void run() {
    	        HttpGet httpget = new HttpGet(url);
    	        HttpResponse response;
    	        try {
    	            response = httpClient.execute(httpget);
    	            callback.onResponseReceived(response);
    	        } catch (Exception ex) {
    	        	callback.onError(ex);
    	        }
    		}
    	};
    	thread.start();
    }

    public static void doPost (final String url,final JSONObject json, final RequestCallback callback) {
    	Log.i("doPost a url: " + url, "- JSON: " + json.toString());
    	final HttpClient httpClient = new DefaultHttpClient();
    	HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 10000);
    	Thread thread = new Thread(){
    		public void run() {
    			HttpPost httpPost = new HttpPost(url);
    	    	httpPost.addHeader("Accept", "application/json");
    	    	httpPost.addHeader("Content-Type", "application/json");
    	    	try {
    	    	    StringEntity entity = new StringEntity(json.toString(), "UTF-8");
    	    	    entity.setContentType("application/json");
    	    	    httpPost.setEntity(entity);
    	    	    // execute is a blocking call, it's best to call this code in a thread separate from the ui's
    	    	    HttpResponse response = httpClient.execute(httpPost);
    	    	    callback.onResponseReceived(response);
    	    	}
    	    	catch (Exception ex) {
    	    		callback.onError(ex);
    	    	}
    		}
    	};
    	thread.start();
    }

    public static void doPut (final String url,final JSONObject json,final RequestCallback callback) {
    	Log.i("doPut a url: " + url, "- JSON: " + json.toString());
    	final HttpClient httpClient = new DefaultHttpClient();
    	HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 10000);
    	Thread thread = new Thread(){
    		public void run() {
    			HttpPut httpPut = new HttpPut(url);
    			httpPut.addHeader("Accept", "application/json");
    			httpPut.addHeader("Content-Type", "application/json");
    	    	try {
    	    	    StringEntity entity = new StringEntity(json.toString(), "UTF-8");
    	    	    entity.setContentType("application/json");
    	    	    httpPut.setEntity(entity);
    	    	    HttpResponse response = httpClient.execute(httpPut);
    	    	    callback.onResponseReceived(response);
    	    	}
    	    	catch (Exception ex) {
    	    		callback.onError(ex);
    	    	}
    		}
    	};
    	thread.start();
    }

    public static void doDelete (final String url, final RequestCallback callback) {
    	Log.i("doDelete" , " - url: " + url);
    	final HttpClient httpClient = new DefaultHttpClient();
    	HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 10000);
    	Thread thread = new Thread(){
    		public void run() {
    			HttpDelete httpDelete = new HttpDelete(url);
    			httpDelete.addHeader("Accept", "application/json");
    	    	try {
    	    	    HttpResponse response = httpClient.execute(httpDelete);
    	    	    callback.onResponseReceived(response);
    	    	}
    	    	catch (Exception ex) {
    	    		callback.onError(ex);
    	    	}
    		}
    	};
    	thread.start();
    }
}

Para hacer consultas desde el emulador a un servidor en la propia máquina, esto es, una consulta ‘localhost’, debes usar la IP 10.0.2.2

GWT con REST

Junio 15th, 2010

Con este ejemplo, se muestra una forma de usar la nueva clase CellTable, que viene en GWT 2.1 para crear una interfaz de usuario sobre los servicios REST que se explicaron en este post.
Para ver como queda la cosa sin tener que instalar nada, se puede acceder a los servicios REST a través de aquí, y a la interfaz de usuario a través de aquí.

Si se utiliza Firefox existe un Addon, JSONView, que hace más amigable el trato con información en formato JSON.

Para ver el ejemplo en local habría que ejecutar desde el directorio raíz del archivo descomprimido:
grails run-app
Y acceder a través de:
http://localhost:8080/GrailsRestExample/gwt/index

Si se desea generar el archivo war para proceder a su instalación en un contenedor J2EE, habría que ejecutar desde el directorio raíz del archivo descomprimido el comando:
grails war
Y proceder a su instalación como cualquier aplicación web Java. Las aplicaciones Grails son aplicaciones web Java.

REST con Grails

Junio 12th, 2010

Para ejecutar el ejemplo hay que tener instalado Grails 1.3.1, descargarse el ejemplo , descomprimir el archivo y ejecutar en el directorio raíz del mismo:
grails run-app

No lo he complicado mucho para que el que quiera arrancar con Grails y REST se lie lo menos posible.
La aplicación consta de tres recursos, Usuario, Voto y Asunto. Se puede probar usando el programa rest-client o el Addon de Firefox ‘Poster’.

Recurso ‘Usuario’

  • Si se quieren consultar los usuarios se debe hacer una petición

GET http://localhost:8080/GrailsRestExample/users?max=20&offset=2

Donde max es el número máximo de resultados devueltos (por defecto 20) y offset es el índice a partir del que se desea obtener el primer resultado (por defecto 0)

  • Para obtener la información de un usuario concreto:

GET http://localhost:8080/GrailsRestExample/users/${idUsuario}

  • Para borrar un usuario se debe hacer una petición:

DELETE http://localhost:8080/GrailsRestExample/users/${idUsuario}

  • Para actualizar un usuario existente habría que hacer una petición:

PUT http://localhost:8080/GrailsRestExample/users/${idUsuario}
Enviando una representación JSON del usuario que se desee crear con las siguientes características:
{"username":"username", "email":"email@gruposp2p.org", "dateOfBird":"01-02-2003","enabled":"true"}

  • Para crear un nuevo usuario habría que hacer una petición

POST http://localhost:8080/GrailsRestExample/users
Enviando una representación JSON del usuario que se desee crear con las siguientes características:
{"username":"username", "email":"email@gruposp2p.org", "dateOfBird":"01-02-2003","enabled":"true"}

Recurso ‘Asunto’

  • Si se quieren consultar los Asuntos dados de alta en el sistema se debe hacer una petición

GET http://localhost:8080/GrailsRestExample/subjects?max=20&offset=2
Donde max es el número máximo de resultados devueltos(por defecto 20) y offset es el índice a partir del que se desea obtener el primer resultado (por defecto 0)

  • Para obtener la información de un asunto concreto:

GET http://localhost:8080/GrailsRestExample/subjects/${idSubject}

  • Para actualizar un asunto existente habría que hacer una petición:

PUT http://localhost:8080/GrailsRestExample/subjects/${idSubject}
Enviando una representación JSON del asunto que se desee crear que tenga siguientes características:
{"content":"Contenido del asunto 40","name":"Nombre del asunto40"}

  • Para borrar un asunto:

DELETE http://localhost:8080/GrailsRestExample/subjects/${idSubject}

Recursos ‘Asuntos’ asociados a un determinado recurso ‘Usuario’

  • Para obtener todos los asuntos generados por un usuario concreto

GET http://localhost:8080/GrailsRestExample/users/${idUsuario}/subjects/

  • Para generar un nuevo asunto asociado al usuario ${idUsuario} habría que hacer una petición

POST http://localhost:8080/GrailsRestExample/users/${idUsuario}/subjects/
Enviando una representación JSON del asunto que se desee crear con las siguientes características:
{"content":"Contenido del asunto 40","name":"Nombre del asunto40"}

Recurso ‘Voto’

  • Si se quieren consultar todos los Votos dados de alta en el sistema se debería hacer una petición

GET http://localhost:8080/GrailsRestExample/votes?max=20&offset=2
Donde max es el número máximo de resultados devueltos (por defecto 20) y offset es el índice a partir del que se desea obtener el primer resultado (por defecto 0)

  • Si se quiere consultar un voto concreto

GET http://localhost:8080/GrailsRestExample/votes/${idVote}

  • Si se quiere modificar un voto habrá que hacer una petición

PUT  http://localhost:8080/GrailsRestExample/votes/${idVote}
Enviando una representación JSON del asunto que se desee crear que tenga siguientes características:
{"value":"valor del voto www"}

  • Para eliminar un voto:

DELETE http://localhost:8080/GrailsRestExample/votes/${idVote}

Votos asociados a un determinado usuario

  • Para obtener todos los votos generados por el usuario ${idUsuario}

GET http://localhost:8080/GrailsRestExample/users/${idUsuario}/votes/

  • Para generar un nuevo voto sobre el asunto ${idSubject} asociado al usuario ${idUsuario} habría que hacer una petición

POST http://localhost:8080/GrailsRestExample/users/${idUsuario}/subjects/${idSubject}
Con una representación JSON del voto que tuviera las siguientes características:
{"value":"valor del voto www"}

Votos asociados a un determinado asunto
GET http://localhost:8080/GrailsRestExample/subjects/{idSubject}/votes

Votos asociados a un determinado asunto y a un determinado usuario
GET http://localhost:8080/GrailsRestExample/users/${idUsuario}/subjects/{idSubject}/votes

En el siguiente artículo explicaré cómo usar las nueva clase TableCell que viene con GWT 2.1 utilizando los datos disponibles en estos servicios REST, la aplicación de acceso para Android la dejaré para el final de esta serie.

Es importante quedarse con los siguientes puntos:

  • Existen formas de securizar los recursos.
  • El desarrollo está hecho en Grails, pero utilizando principios REST pueden crearse servicios, independientes de lenguaje de programación y plataforma, accesibles a través de Internet.
  • Gracias a esta técnica se separa completamente la interfaz de usuario del servicio.
  • Si se desea que dos partes intercambien información a través de Internet la mejor forma de conseguirlo es empezando definiendo las interfaces REST de los recursos que se desean compartir.

Modelos de datos

Diciembre 24th, 2009

Independientemente del lenguaje que se vaya a usar para la implementación un buen diagrama del modelo de datos es útil en cualquier desarrollo. Viendo ese diagrama es posible hacerse una idea de la aplicación.
La herramienta que utilizo para crear el modelo, Power Architect, permite generar los scripts de creación de tablas para varias bases de datos a partir del modelo.
Aquí se puede ver el modelo con el que voy a empezar a trabajar en este proyecto.
Una vez se tienen las tablas de la base de datos existen herramientas que generan las entidades JPA de forma automática a partir de las mismas. Yo suelo generar esas entidades, las retoco para que generen los ‘id’ de forma automática y las anoto con anotaciones JAXB para que Jersey pueda hacer las transformaciones de objetos a representaciones XML/JSON y viceversa.

Entidades JPA con anotaciones JAXB y Spring, anda que no  se concentra información funcional ni nada en tan poco espacio.
En el próximo post explicaré como integrar el motor de búsqueda Hibernate Search.
Hibernate Search utiliza Apache Lucene como motor de búsqueda, una herramienta que permite hacer búsquedas profesionales sobre grandes cantidades de texto.