REST y campos ocultos

[Este es un followup a un comentario que hice esta tarde durante la
ponencia de Juan Quemada y Joaquin Salvachua.]

Cuando comente lo de los hidden fields quedo la cosa ahi como medio
descolgada porque me di cuenta de que necesitaria elaborar el tema
para explicar la analogia pero no me parecia que fuera el momento
adecuado, asi que lo deje correr, pero sigo por aqui :-).

Cuando uno usa un hidden field para pasarse contexto en web
tradicional esta enviando al cliente datos que son necesarios para la
siguiente peticion. De manera que la siguiente peticion acarrea los
datos necesarios para poder servirse. El campo se hace oculto por
usabilidad, no por seguridad. Se hace oculto porque en la web humana
ese es un campo que tecnicamente necesitas pero que al usuario no le
aporta nada, y por tanto no se lo muestras. Por supuesto, como todo en
web, uno no puede confiar en que lo que viene del cliente no haya
podido ser manipulado y has de validar que el request tiene sentido,
que el usuario esta autorizado a hacer lo que pide, etc.

Bien, en REST una de las premisas es que las peticiones debe
transportar todo lo necesario para que pueda realizarse la operacion
demandada sobre el recurso al que te refieres. Por tanto esa practica
es RESTful.

Un ejemplo de uso “analogo” de campo hidden en servicios web RESTful
es el modelado de transacciones como hacen en el libro de O’Reilly que
Juan y Joaquin recomendaron.

Cuando en REST se dice que todo son recursos no se quiere decir que
los recursos mapeen a tu modelo de datos uno a uno. El concepto de
recurso esta abierto y depende de cada aplicacion, de lo que tenga
sentido en ella. Puede ser algo logico (/releases/latest versus /
releases/{id}) y abstracto, ad-hoc, como seria el de transaccion. Si
tu aplicacion necesita transacciones, visto RESTful, es que en tu
aplicacion aparece un recurso “transaccion” que no es ni mas ni menos
en el modelo conceptual que el recurso mas llano “account”.

Para realizar una operacion bancaria haces lo siguiente, primero creas
un recurso transaccion:

POST /transaction/account-transfer

y devuelves un 201 Created con la URL del recurso creado en Location
(esto es estandard):

201 Created
Location: /transaction/account-transfer/45

El contrato con el cliente, documentado, es que las operaciones a
realizar dentro de esa transaccion van ahi debajo:

PUT /transactions/account-transfer/45/account/checking/23
balance=150

y cuando terminaste haces un DELETE del recurso transaccion para
rollback, o bien haces un commit

PUT /transactions/account-transfer/45

committed=true

Bien, eso en mi opinion es analogo a la tecnica del hidden field en
web humana. Le has enviado al cliente algo para que te lo vaya pasando
en subsiguientes peticiones. Si el request es invalido (el recurso
transaccion no viene, o no existe, o tratas de usar una que no es tuya
manipulando el ID, etc.) devuelves un 4xx. Esas son las mismas
validaciones que harias con un campo oculto tambien.

– fxn

P.D.: Saludos a todos ya desde Barcelona, ha sido una conferencia
cojonuda :-).

El 24/11/2007, a las 1:13, Xavier N. escribió:

– fxn

P.D.: Saludos a todos ya desde Barcelona, ha sido una conferencia
cojonuda :-).

por dios xavier duerme!

On Nov 24, 2007, at 11:19 PM, Juan Quemada wrote:

Hola Juan,

Gracias por los comentarios, porque el concepto
de stateless no es facil de explicar.

Estoy de acuerdo. El libro de O’Reilly (400+ paginas de primera
calidad, desde luego que subscribo la recomendacion de Juan y Joaquin)
me ha ayudado muchisimo a cuadrar las cosas ya que te explica los
fundamentos. Una vez entiendes los fundamentos lo demas se sigue. Y
aun y asi implementamos en ASPgems un servicio web puro REST muy pero
que muy sencillo
(una pasarela de reservas de hoteles), nos
esforzamos en que fuera canonicamente REST, y surgieron algunas dudas
que en rest-discuss me ayudaron a resolver. En vuestra charla
observasteis algo que comparto del todo por mi experiencia, las reglas
de juego son sencillas, pero hacer el modelo basado solo en recursos
puede costar hasta que no lo tengas por la mano.

Y aun en mi caso estoy acostumbrado a hacer web sin estado, por eso
apoyo el cambio a cookie-based sessions por defecto en la 2.0 (hay un
thread en -core), porque en mis sesiones solo hay un user_id y
eventualmente un flash. Nada mas. Lo que me ha costado es pensar
estrictamente en recursos, interfaz unica, y codigos HTTP. Quien este
acostumbrado a tirar de sesion en web tiene aun mas que batallar.

Es un paradigma distinto, y cuesta hasta que no aprendes a pensar con
esas reglas (como en cualquier cambio de paradigma). Asi que pienso
como vosotros que el curso que preparais tiene un reto pedagogico
importante.

Cuando hablas de la transacción bancaria me
da la impresion que es la tipica transacción
con varias operaciones que no se pueden
consolidar hasta que se finaliza la secuencia
y se realiza el commit o el rollback, que también
es un truco para implementar transacciones
multioperación en un entorno REST.

Exacto. De hecho honestamente creo que eso es un medio cambalache,
porque estas como disfrazando estado con un recurso. En una operacion
donde debes quitar de aqui y poner alli atomicamente pero usando
distintas peticiones, estas estan vinculados. No hay tu tia. Tal como
se propone en el libro si la transaccion ni la comitea (heh :-), ni la
borra, se queda ahi de basura. Ya que ellos proponen en esa tecnica
(hay mas) que el recurso transaccion tenga como estado lo que debe
hacer, para ejecutarlo en commit, borrarlo si rollback, y para que
mientras la transaccion esta abierta el resto de la aplicacion vea los
objetos afectados como estan “fuera” de la transaccion.

Eso a mi modo de ver es casi casi una sesion con el nombre cambiado.
Te lo puedes mirar como un recurso si, peroooo, tengo mixed-feelings
la verdad.

Lo REST seria que pudieras decir en una sola request todo lo que
necesites que sea atomico. Ahi bien. Si tu aplicacion necesariamente
tiene peticiones separadas y vinculadas y no son una excepcion podria
pasar que REST no sea lo mas adecuado en mi opinion, habria que ver.
Si la aplicacion puede ser stateless perfecto, si no puede ser
stateless creo que lo apropiado es aplicar otro paradigma.

No en vano en el libro dedican bastante a hablar de transacciones,
creo que es porque esta ahi en la frontera y es un ejercicio dificil
encajarlas en las premisas REST.

Si pudiera humildemente aportar algo al curso de la forma que fuere
desde luego que podeis contar conmigo.

– fxn

Podrían indicar de que libro están hablando?

Gracias.

On Nov 25, 2007, at 1:45 AM, Listas de Correo wrote:

Podrían indicar de que libro están hablando?

Seguro, es este:

RESTful Web Services [Book]

– fxn

Gracias

On Nov 24, 2007, at 1:13 AM, Xavier N. wrote:

pide, etc.
De cara a los archivos voy a poner otro ejemplo mas sencillo que el de
las transacciones, donde la analogia con el campo oculto se limitaba
al recurso transaccion mismo, pero luego el uso de la transaccion
conllevaba como un medio estado que es otra cosa y puede liar (lo he
comentado en otro mail).

Supongamos que estamos en gestion de un catalgo de productos, y en el
arbol de categorias pone “añadir subcategoria” junto a cada categoria.
Supongamos que eso nos lleva a una pantalla de creacion de
(sub)categoria. Como nos acordamos de la categoria padre? Las opciones
tradicionales son

  1. Metemos el ID de la padre en sesion (NO HACER ESTO)

  2. Metemos el ID de la padre en un campo oculto

La opcion 2 es la stateless, la 1 almacena estado en el servidor.

Cuando el formulario viene con la 2 no es necesario comprobar que el
ID fue el que se puso, solo es necesario comprobar que la categoria
asociada existe y que el usuario puede colgar subcategorias de esa. Si
manipulo el ID y puso un 37 en lugar de un 25 nos da lo mismo (por lo
general) mientras se cumpla lo anterior. Si el usuario esta haciendo
esto con dos ventanas abiertas a la vez del mismo navegador nos da lo
mismo, cada formulario lleva todos los datos necesarios. Si hizo back
y reenvia el formulario nos da lo mismo, porque siempre validamos.
Puede que cree dos subcategorias iguales dandole al back si la
aplicacion admite nombre duplicados, pero eso esta bien si esas son
las peticiones que envio. El caso es que cada peticion tiene sentido
suelta, es procesable porque acarrea todo lo necesario.

En REST, la opcion del campo oculto se puede traducir analogamente a

  1. Metemos el ID de la padre en la URL del action
    del formulario

Y si se trata de un web service la interfaz uniforme nos dice que se
esperaria tener que hacer un POST a la direccion de la categoria
padre. En ese sentido es que en REST se solucionan las cosas “al
estilo” de como hacemos con campos ocultos en programacion web
tradicional sin estado.

– fxn