Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

CRUD en Symfony y métodos HTTP

12 de julio de 2015

Hola de nuevo,

Para el desarrollo de mi web, estoy creando funcionalidades CRUD para que el centro que se loguee mantenga sus usuarios, cursos, materias, libros, entregas de libros, reservar. Y para todos ellos estoy partiendo del código que genera Symfony automáticamente, porque me queda todo muy ordenado, cada CRUD con su propio controlador, archivo de enrutamiento, carpeta de views/... Y cada cual con sus voters y formularios.

Como se trata de un proyecto fin de carrera, y como sigo la misma estructura en todo, antes de avanzar me gustaría entender bien el esquema que genera Symfony con los métodos de HTTP, porque quiero hacer las cosas correctamente.

Un ejemplo (todas estas rutas van cargadas con un prefijo)

extranet_reserva:
    path:     /
    defaults: { _controller: "ExtranetBundle:Reserva:index" }

extranet_reserva_show:
    path:     /{id}/show
    defaults: { _controller: "ExtranetBundle:Reserva:show" }

extranet_reserva_new:
    path:     /new
    defaults: { _controller: "ExtranetBundle:Reserva:new" }

extranet_reserva_create:
    path:     /create
    defaults: { _controller: "ExtranetBundle:Reserva:create" }
    requirements: { _method: post }

extranet_reserva_edit:
    path:     /{id}/edit
    defaults: { _controller: "ExtranetBundle:Reserva:edit" }

extranet_reserva_update:
    path:     /{id}/update
    defaults: { _controller: "ExtranetBundle:Reserva:update" }
    requirements: { _method: post|put }

extranet_reservas_delete:
    path:     /{id}/delete
    defaults: { _controller: "ExtranetBundle:Reserva:delete" }
    requirements: { _method: post|delete }

Me centro en la parte que más dudas me ofrece: la edición.

Parto de la base de que:

  • POST: creates a new resource.
  • GET: retrieves a resource.
  • PUT: updates an existing resource.
  • DELETE: deletes a resource.

Por lo que he repasado de los métodos HTTP, y por lo visto en la web, no me basta con usar estos métodos, y repetir algo de código al tener más acciones extra en el controlador, sino que la cosa debe ir acorde realmente con lo que quiero hacer. Se supone que PUT se aplica a acciones idempotentes. Y ahí ya entra que le navegador recargue la página y no surjan efectos colaterales.

El caso es que no acabo de entender 100% ésto pero debo acabar entendiéndolo tarde o temprano. Lo que necesataría ahora es un poco de ayuda para dar con una estrutura correcta (pues la uso en muchos controladores) de forma que cuando profundice con la documentaciòn no me obligue a refactorizar demasiado.

De forma natural tiendo a prescindir de "update" y hago toda la edición en una sóla accion de "edit". Y con isValid() sé si el origen es GET o POST. Pero en el momento que quiero hacer PUT, ya tengo que dividir en dos acciones. ¿Me equivoco?

Gracias de antemano.


Respuestas

#1

Este tipo de preguntas siempre son difíciles de contestar. Por una parte, en el mundo ideal de los estándares, usar métodos como PUT y DELETE es "lo correcto". Pero por otra parte, en el mundo real de los navegadores, sólo funcionan los métodos GET y POST. Para aplicaciones web yo me limitaría a hacer todo con GET y POST y dejaría el resto de métodos para las APIs.

En cualquier caso, el propio generador CRUD de Symfony ya te genera todas las acciones para crear, editar, etc. y cada una utiliza el método HTTP "correcto": la acción update usa PUT, la acción create usa POST, etc. En este caso, yo me limitaría a usar directamente como base el código generado por Symfony.

@javiereguiluz

12 julio 2015, 22:45
#2

Gracias. Anoto esta cuestión para documentarla. Y me decido por compatibilidad con navegadores y HTML5 por esta estructura:

#Petición de lista de recursos (GET)
extranet_usuario:
    path:     /
    defaults: { _controller: "ExtranetBundle:Usuario:index" }
 
#Petición de recurso concreto (GET)
extranet_usuario_mostrar:
    path:     /{id}/mostrar
    defaults: { _controller: "ExtranetBundle:Usuario:mostrar" }
 
#Petición de crear nuevo recurso (GET)
#Envío de datos para crear un nuevo recurso (POST)
extranet_usuario_crear:
    path:     /crear
    defaults: { _controller: "ExtranetBundle:Usuario:crear" }
    requirements: { _method: get|post }
 
#Petición de edición de recurso concreto (GET)
#Envío de datos para actualización de recurso concreto (POST)
extranet_usuario_editar:
    path:     /{id}/editar
    defaults: { _controller: "ExtranetBundle:Usuario:editar" }
    requirements: { _method: get|post }
 
#Borrado de un recurso concreto (POST)
extranet_usuario_eliminar:
    path:     /{id}/eliminar
    defaults: { _controller: "ExtranetBundle:Usuario:eliminar" }
    requirements: { _method: post }

@nando_sosa

13 julio 2015, 12:07