¿Por qué necesitamos servicios web RESTful?


123

Voy a aprender servicios web RESTful (es mejor decir que tendré que hacer esto porque es parte del programa de maestría de CS).

He leído algo de información en Wikipedia y también he leído un artículo sobre REST en Sun Developer Network y veo que no es una tecnología fácil, hay marcos especiales para crear aplicaciones RESTful, y a menudo se compara con los servicios web SOAP y el programador debe entender cuándo usar SOAP y cuándo REST podría ser un buen enfoque.

Recuerdo que hace varios años SOAP era muy popular (¿de moda?) Y el artículo 'SOAP' tenía que estar presente en cada buen CV. Pero en la práctica se usó muy raramente y para lograr propósitos muy simples.

Me parece que REST es otra 'última palabra de moda' (o puedo estar totalmente equivocado porque nunca he visto REST en la práctica).

¿Puede darme algunos ejemplos en los que REST debería usarse y por qué no podemos hacer lo mismo sin REST (o por qué deberíamos dedicar mucho más tiempo a hacer lo mismo sin REST)?

UPD : Desafortunadamente, no puedo ver ningún argumento concreto que pueda sorprenderme en los primeros comentarios. ¡Hazme pensar que REST es una tecnología increíble!

Me gustaría ver respuestas como esta:

Estaba desarrollando otra aplicación HelloWorld compleja y necesitamos transferir muchos / pequeños datos y propuse una solución REST a mi compañero de trabajo:

- ¡Oh demonios! Jonny, ¡ciertamente deberíamos usar REST para implementar esta aplicación!
- Sí, Billy, podemos usar REST, pero sería mejor usar SOAP. Confía en mí porque sé algo sobre el desarrollo de aplicaciones HelloWorld.
- Pero SOAP es una tecnología pasada de moda del siglo pasado y podemos usar una mejor.
- Billy, ¿estás listo para pasar 3 días para experimentar con REST? Podemos hacer esto con SOAP en 2 horas.
Sí, estoy seguro de que pasaremos aún más tiempo para lograr la misma seguridad / rendimiento / escalabilidad / lo que sea con SOAP. Estoy seguro de que las aplicaciones HelloWorld deberían desarrollarse solo con REST a partir de ahora.


2
No es una tecnología increíble, es una tecnología diferente. Si quiere que alguien lo convenza, es increíble y debe usarse siempre, intente con un consultor.
Quillbreaker

Respuestas:


133

REST debe usarse si es muy importante para usted minimizar el acoplamiento entre los componentes del cliente y el servidor en una aplicación distribuida.

Este puede ser el caso si su servidor va a ser utilizado por muchos clientes diferentes sobre los que no tiene control. También puede ser el caso si desea poder actualizar el servidor regularmente sin necesidad de actualizar el software del cliente.

Les puedo asegurar que lograr este bajo nivel de acoplamiento no es fácil de hacer . Es fundamental seguir todas las limitaciones de REST para tener éxito. Mantener una conexión puramente sin estado es difícil. Elegir los tipos de medios correctos y exprimir sus datos en los formatos es complicado. Crear tus propios tipos de medios puede ser aún más difícil.

Adaptar el comportamiento del servidor enriquecido en la interfaz HTTP uniforme puede ser confuso y, a veces, parece pedante en comparación con el enfoque RPC relativamente sencillo.

A pesar de las dificultades, los beneficios son que tiene un servicio que el desarrollador de un cliente debería poder entender fácilmente debido al uso constante del protocolo HTTP. El servicio debe ser fácilmente detectable debido a hipermedia y el cliente debe ser extremadamente resistente a los cambios en el servidor .

Los beneficios del hipermedia y la evitación del estado de la sesión hacen que el equilibrio de carga sea simple y la partición del servicio sea factible . La estricta conformidad con las reglas HTTP hace que la disponibilidad de herramientas como depuradores y servidores proxy de almacenamiento en caché sea algo maravilloso.

Actualizar

Me parece que REST es otra 'última palabra de moda' (o puedo estar totalmente equivocado porque nunca he visto REST en la práctica).

Creo que REST se ha puesto de moda porque las personas que intentan hacer proyectos de tipo SOA han descubierto que al usar la pila SOAP no se están dando cuenta de los beneficios prometidos. La gente sigue volviendo a la web como un ejemplo de metodologías de integración simples. Desafortunadamente, creo que las personas subestiman la cantidad de planificación y previsión que se necesitó para crear la web y simplifican demasiado lo que se debe hacer para permitir el tipo de reutilización fortuita que ocurre en la web.

Dices que nunca has visto REST en la práctica, pero eso no puede ser cierto si alguna vez usas un navegador web. El navegador web es un cliente REST.

  • ¿Por qué no necesita hacer una actualización del navegador cuando alguien cambia algo de HTML en un sitio web?
  • ¿Por qué puedo agregar un nuevo conjunto completo de páginas a un sitio web y el "cliente" aún puede acceder a esas nuevas páginas sin una actualización?
  • ¿Por qué no necesito proporcionar un "lenguaje de descripción de servicio" al navegador web para decirle cuándo va a http://example.org/images/cat que el tipo de retorno será una imagen jpeg y cuando vaya a http://example.org/description/cat el tipo de retorno será text / html?
  • ¿Por qué puedo usar un navegador web para visitar sitios que no existían cuando se lanzó el navegador? ¿Cómo puede el cliente saber acerca de estos sitios?

Esto puede sonar como preguntas tontas, pero si conoce la respuesta, puede comenzar a ver de qué se trata REST. Mire StackOverflow para obtener más beneficios de REST. Cuando estoy mirando una pregunta, puedo marcar esa página o enviar la URL a un amigo y él puede ver la misma información. No tiene que navegar por el sitio para encontrar esa pregunta.

StackOverflow utiliza una variedad de servicios OpenId para autenticación, gravatar.com para imágenes de avatar, google-analytics y Quantserve para información analítica. Este tipo de integración multiempresarial es el tipo de cosas con las que el mundo SOAP solo sueña . Uno de los mejores ejemplos es el hecho de que las bibliotecas jQuery que se utilizan para controlar la interfaz de usuario de StackOverflow se recuperan de la red de entrega de contenido de Google. El hecho de que SO pueda dirigir al cliente (es decir, su navegador web) a descargar código de un sitio de terceros para mejorar el rendimiento es un testimonio del bajo acoplamiento entre el cliente web y el servidor.

Estos son ejemplos de una arquitectura REST en el trabajo.

Ahora, algunos sitios web / aplicaciones rompen las reglas de REST y luego el navegador no funciona como se esperaba.

  • El infame problema del botón de retroceso se debe al uso del estado de sesión del lado del servidor.
  • El equilibrio de carga puede convertirse en un problema cuando tiene un estado de sesión del lado del servidor.
  • Las aplicaciones Flash a menudo evitan que la URL identifique específicamente una representación.
  • El otro problema que rompe los navegadores web es la pobre conformidad con los estándares de tipo multimedia. Escuchamos todo el tiempo acerca de cómo IE6 necesita ser asesinado. El problema es que los estándares no se siguieron correctamente o se ignoraron por cualquier motivo.
  • El uso de sesiones de inicio de sesión es la fuente de muchos agujeros de seguridad.

El descanso está en todas partes. Es la parte de la web que hace que funcione bien. Si desea crear aplicaciones distribuidas que se puedan escalar como la web, sea resistente a los cambios como la web y promueva la reutilización como lo ha hecho la web, luego siga las mismas reglas que al crear navegadores web.


@Darrell: ¿cómo en el mundo REST reduce el acoplamiento sobre SOAP? O, ¿cómo aumenta SOAP el acoplamiento sobre REST? ¿Se refiere al hecho de que un cliente SOAP realmente necesita comprender SOAP, pero un cliente REST solo necesita comprender los tipos de medios?
John Saunders, el

44
@John Generalmente, la forma en que se usa SOAP hace que el cliente requiera conocimiento "compilado" de cada punto final del lado del servidor, cada tipo de datos de parámetros y cada tipo de retorno. No existe una guía en el mundo SOAP para intentar usar tipos estandarizados para pasar datos entre el cliente y el servidor. Eso significa que cada nuevo servicio que va a utilizar un desarrollador de cliente tiene su propio conjunto único de tipos, puntos finales y protocolo de interacción. Eso es acoplamiento.
Darrel Miller, el

@John REST intenta estandarizar el protocolo de interacción con la semántica de los verbos HTTP, los formatos de datos para los tipos registrados de IANA y todos los puntos finales deben ser dinámicamente detectables. Eso significa que el acoplamiento cliente / servidor está localizado en la definición del tipo de medio. Tal como dijo Rich, "su servicio reduce el alcance del acoplamiento a una sola cosa: los tipos de medios".
Darrel Miller, el

@Darrell: eso no es acoplamiento en el sentido tradicional. Se puede considerar que el cliente está "acoplado" a metadatos (WSDL), pero no al servicio. Considere un servicio que devuelve un "Empleado": {int id; string firstName, lastName, streetAddress1, streetAddress2, city, state; int zip;}. Parece sugerir que registramos "Empleado" con IANA, o que simplemente consideramos que "Empleado" es una matriz asociativa de pares de nombre / valor.
John Saunders

@ John Permítanme definir lo que quiero decir por acoplamiento en términos WSDL. Imagine poder tener un contrato de servicio al que podría agregar métodos, eliminar métodos y cambiar el nombre de los métodos sin tener que volver a compilar el cliente. Considere también que el cliente podría ser dirigido a usar estos nuevos métodos sin recompilación. El contrato de mensajes está arreglado por HTTP pero es extensible a través de encabezados y el contrato de datos es el único cambio que podría romper un cliente, sin embargo, al usar metadatos en el contrato de mensajes, el servidor podría entregar dinámicamente la versión apropiada del contrato de datos al cliente.
Darrel Miller

11

REST fue iniciada, según mi conocimiento, por la disertación de Roy Fielding, Architectural Styles y el diseño de arquitecturas de software basadas en red , que vale la pena leer si no lo ha mirado.

En la parte superior de la disertación hay una cita:

Casi todo el mundo se siente en paz con la naturaleza: escuchando las olas del océano contra la orilla, junto a un lago tranquilo, en un campo de hierba, en un brezo soplado por el viento. Un día, cuando hayamos aprendido el camino atemporal de nuevo, sentiremos lo mismo por nuestros pueblos, y nos sentiremos tan tranquilos en ellos, como lo hacemos hoy caminando por el océano, o tumbados en la hierba larga de un prado.

- Christopher Alexander, La forma intemporal de construir (1979)

Y eso realmente lo resume allí. REST es en muchos sentidos más elegante.

SOAP es un protocolo sobre HTTP, por lo que omite muchas convenciones de HTTP para construir nuevas convenciones en SOAP y es redundante en varias formas con HTTP. Sin embargo, HTTP es más que suficiente para recuperar, buscar, escribir y eliminar información a través de HTTP, y eso es mucho de lo que es REST. Debido a que REST está construido con HTTP en lugar de encima, también significa que el software que desea integrarse con él (como un navegador web) no necesita comprender SOAP para hacerlo, solo HTTP, que tiene que ser el más ampliamente entendido e integrado, con el protocolo en uso en este momento.


SOAP se definió en 1998. ¿Cuántas "convenciones" HTTP eran convenciones en aquel entonces?
John Saunders, el

De acuerdo con esto w3.org/Protocols/HTTP/1.0/spec.html HTTP ha estado en uso desde 1990. ¿Y qué? Todos sabemos que la única razón por la que SOAP usa http fue porque el puerto 80 tenía más probabilidades de estar abierto en el firewall. Microsoft no iba a cometer el error DCOM nuevamente.
Darrel Miller, el

1
" REST está construido con HTTP en lugar de encima " +1. Todo este hilo es realmente útil para mí para comprender la validez del uso de REST sobre SOAP y viceversa.
Chris22

9

Desde aquí :

Ventajas de RESTO:

  • Ligero: no hay muchas marcas adicionales de XML
  • Resultados legibles para humanos
  • Fácil de construir: no se requieren kits de herramientas

También mira esto :

Para ser justos, REST no es la mejor solución para todos los servicios web. Los datos que deben ser seguros no deben enviarse como parámetros en los URI. Y grandes cantidades de datos, como los de pedidos de compra detallados, pueden convertirse rápidamente en engorrosos o incluso fuera de límites dentro de un URI. En estos casos, SOAP es de hecho una solución sólida. Pero es importante probar REST primero y recurrir a SOAP solo cuando sea necesario. Esto ayuda a mantener el desarrollo de aplicaciones simple y accesible.


44
El comentario contras no es muy correcto. Al mover un parámetro del URI al cuerpo, esto aún no es seguro. Use SSL por seguridad. Además, cuando los datos en la uri pueden ser muy largos, puede usar la publicación y ponerla en el cuerpo. La mayoría de los lenguajes del lado del servidor combinan los datos de los parámetros URI y los parámetros POST, por lo que no se necesita ningún cambio en el servidor.
Emil Ivanov

1
@Emil: tenga en cuenta que SSL no siempre está disponible. Algunas personas quieren seguridad basada en mensajes y no seguridad basada en el nivel de transporte. Y en cuanto al uso del cuerpo de un POST ... POST es uno de los verbos utilizados para procesar solicitudes REST. No siempre se puede reutilizar para satisfacer sus necesidades.
Justin Niessner

1
Una gran CON: no estandarizada "Descripción" lenguaje como WSDL para los servicios SOAP - todas las fuerzas servicio REST o no podría ser documentada, y la calidad de la documentación es muy diferente a la oferta de servicios a otro .....
marc_s

3
@Marc_s Si REST se realiza correctamente, no es necesario un "lenguaje de descripción" como WSDL. Los tipos de medios utilizados deben documentarse, pero no debe existir documentación que combine los puntos finales con los tipos de medios.
Darrel Miller

@Darrel: Lo siento, no compro el sinsentido "sin lenguaje de descripción". Incluso si los tipos de documentos están documentados, también deben describirse. Además, a algunas personas les gusta deserializar el contenido en objetos en un lenguaje de programación. En ese caso, es muy útil tener una definición legible por máquina de lo que el servicio puede enviar y recibir, para que su herramienta pueda crear las clases correspondientes y el código de serialización.
John Saunders, el

8

Puedo decir con seguridad que he pasado mucho tiempo para entender esto como principiante, ¡pero este es el mejor enlace para comenzar con REST desde cero! http://www.codeproject.com/Articles/21174/Everything-About-REST-Web-Services-What-and-How-Pa

Solo para atraerte,

Piense en lo que es un "servicio web tradicional". Es una interfaz con "métodos" expuestos. Los clientes conocen el nombre, la entrada y la salida de los métodos y, por lo tanto, pueden llamarlos.

Ahora imagine una interfaz que no exponga "métodos". En cambio, expone "objetos". Entonces, cuando un cliente ve esta interfaz, todo lo que ve es uno o más "objetos". "Un objeto" no tiene entrada ni salida, porque "no hace nada". Es un sustantivo, no un verbo. Es "una cosa", no "una acción".

Por ejemplo, piense en un servicio web tradicional que proporcione las condiciones climáticas actuales si le proporciona una ciudad. Probablemente tiene un método web como GetWeatherInfo () que toma una ciudad como entrada y proporciona datos meteorológicos como salida. Hasta ahora es fácil para usted comprender cómo un cliente consumirá este servicio web.

Ahora imagine, en el lugar del servicio web anterior, hay uno nuevo que expone las ciudades como objetos. Entonces, cuando lo miras como un cliente, en lugar de GetWeatherInfo (), ves Nueva York, Dallas, Los Ángeles, Londres, etc. Y estas ciudades no tienen ningún método específico de aplicación que cuelgue de ellas, aparentemente son como gases inertes, ellas mismas no reaccionan.

Debes estar pensando, bueno, ¿cómo te ayuda eso, como cliente, a llegar al clima de Dallas? Llegaremos a eso en unos momentos.

Si todo lo que obtiene de un servicio web es un "conjunto de objetos", obviamente necesita una forma de "actuar sobre ellos". Los objetos en sí no tienen métodos para llamar, por lo que necesita un conjunto de acciones que pueda aplicar a estos objetos. En otras palabras, debe "aplicar un verbo al sustantivo". Si ve un objeto, por ejemplo, una manzana, que es "un sustantivo", puede aplicarle "un verbo" como comer. Pero no todos los verbos se pueden aplicar a todos los sustantivos. Como, puedes conducir un automóvil, pero no puedes conducir un televisor.

Por lo tanto, si un servicio web expone solo objetos, y se le pregunta, bueno, ahora diseñemos algunas acciones o verbos estándar que "todos los clientes pueden aplicar a todos los objetos que ven", ...


Entonces, ¿cuál es el beneficio de tener un objeto en lugar de un método?
Soumya Rauth

4

Aquí hay algunas ideas:

  • REST restringe su servicio para usar una interfaz uniforme. No tiene que perder el tiempo soñando despierto (o discutiendo) sobre todas las posibles formas en que su servicio podría funcionar: puede trabajar identificando los recursos en su sistema. Resulta ser un gran trabajo en sí mismo, pero afortunadamente los problemas tienden a estar mejor definidos.
  • Con los recursos, sus asociaciones y sus representaciones en la mano, realmente hay muy poco que hacer en la implementación de su servicio porque se han tomado muchas decisiones por usted.
  • Su sistema se parecerá mucho a otros sistemas RESTful; se reducirán las curvas de aprendizaje para compañeros de equipo, socios y clientes.
  • Tendrá un vocabulario común para discutir problemas de diseño con otros desarrolladores, e incluso con aquellos con menos conocimientos técnicos (como los clientes).
  • Como dice Darrel, debido a que está utilizando un diseño impulsado por hipertexto , su servicio reduce el alcance del acoplamiento a una sola cosa: los tipos de medios. Esto lo ayuda como desarrollador porque los cambios en su sistema están contenidos dentro de una banda estrecha de contacto. Esto ayuda a sus clientes en que menos de sus cambios romperán su código.
  • Casi todos los problemas que pueda tener al implementar REST se pueden resolver exponiendo un nuevo recurso o replanteando su modelo de recurso. Este enfoque es, en mi opinión, un gran impulso de productividad.

En pocas palabras, REST elimina muchas de las decisiones de diseño e implementación más demandantes y polémicas del flujo de trabajo de su equipo. Cambia su atención de implementar su servicio a diseñarlo . Y lo hace sin acumular gobbledygook en el protocolo HTTP.


@John Si enciendo VS y creo un proyecto WCF y creo una interfaz con el atributo [ServiceContract], puedo agregar cualquier llamada a método que me guste. CreateCustomer (), MakeOrder (), ConfirmOrder (), VerifyOrder (), SubmitOrder (), CheckStockAvailability (), CancelOrder () De esos métodos, ¿puede decirme qué secuencia debo usar para procesar un pedido? ¿Me puede decir cuándo puedo llamar a CancelOrder ()? ¿Debo verificar la disponibilidad antes de confirmar el pedido? ¿Debo verificar el pedido antes de verificar la disponibilidad? Es probable que esta interfaz no sea coherente con la de la nómina.
Darrel Miller, el

1
@Darrel: No veo cómo REST ayuda a resolver esto. ¿ MakeOrderDa URL para ConfirmOrdery CancelOrder? ¿El cliente aún no sabe cómo llamar al servicio, sino que debe estar basado en datos?
John Saunders

1
@ John Exactamente. El cliente sabe que se le pueden proporcionar la URL ConfirmOrder y la URL CancelOrder, pero no sabe cómo se ven esas URL y solo las seguirá si se proporcionan. Lo llamas basado en datos, Roy lo llama Hypermedia como el motor del estado de la aplicación.
Darrel Miller

@Darrel: Supongo que nunca he visto ningún servicio crítico para el negocio en el que quiera determinar a qué llamar a continuación en función de la URL que recibí de la llamada anterior.
John Saunders

1
@ JohnSaunders: eso se debe a que una llamada REST no se trata de llamadas de método, sino de transición de estado (piense en la máquina de estados). En cualquier estado dado, un servidor RESTful especificará transiciones de estado válidas y el usuario o agente de usuario elige las transiciones que desea seguir.
Lie Ryan

4

La mayoría de las respuestas "profesionales" sobre REST parecen provenir de personas que nunca han desarrollado un servicio web SOAP o un cliente que utiliza un entorno que proporciona las herramientas adecuadas para la tarea. Se quejan de problemas que simplemente nunca he encontrado, usando Visual Studio .NET y Rational Web Developer de IBM. Supongo que si tiene que desarrollar servicios web o clientes en un lenguaje de script, o en algún otro idioma con poco o ningún soporte de herramientas, estas son quejas válidas.

También tengo que admitir que varios de los puntos "profesionales" suenan como cosas que en realidad podrían ser ciertas, pero que nunca he visto un ejemplo que ilustre su valor. En particular, agradecería mucho que alguien publicara un comentario que contenga un enlace a un buen ejemplo de un servicio web REST. Este debería ser uno que use múltiples niveles de recursos, posiblemente en una jerarquía, y que use los tipos de medios correctamente. Tal vez si miro un buen ejemplo, lo entiendo, en cuyo caso, volveré aquí y lo admitiré.


El mejor ejemplo público visible hasta la fecha es la API de Sun Cloud. Aquí hay un tutorial kenai.com/projects/suncloudapis/pages/… Solo para calificar mi experiencia con SOAP. He creado, y aún soporto, servicios web ASMX usando la Fábrica de Software de Servicios Web de Microsoft del grupo de Patrones y Prácticas. He creado servicios basados ​​en WCF utilizando una versión posterior de la misma fábrica de software. También utilicé System.ServiceModel.Web de WCF desde que se lanzó por primera vez con el SDK de Servicios de Biztalk en mayo de 2007.
Darrel Miller,

1
John: un ejemplo de una API de descanso es la de Amazon. Tienen una API @SOAP y una REST. Puede ser útil para usted- docs.amazonwebservices.com/AmazonS3/latest/…
RichardOD

3

Para agregar un giro ligeramente prosaico a las respuestas ya dadas la razón por la que usamos los servicios REST donde estoy, es que si sabe que puede entregarle a un socio comercial una URL y sabe que recibirá, a cambio, una losa de XML bien diseñada No importa si están trabajando en .Net xx, PHP, Python, Java, Ruby o Dios sabe, lo que reduce severamente los dolores de cabeza.

También significa que, en el extremo no técnico, nuestro personal de ventas puede presumir de nuestra API versátil para las personas sin temor a parecer muppets completos.

Además de los beneficios técnicos, cualquier cosa que sea fácil de explicar, demostrar y confiar en una persona que no sea técnica es algo bueno. SOAP, aunque igual de interesante para los técnicos es mucho menos accesible para los no técnicos y, por lo tanto, no es tan fácil de "vender".

Tiendo a notar que las cosas que no son expertos en tecnología pueden entender. Así que dudo que REST sea una técnica que pueda ser tan susceptible como SOAP a los caprichos de la moda.

Pero todo lo relacionado con no poner nada en un servicio REST que deba bloquearse es doblemente cierto solo porque la tecnología es tan fácil de entender por personas que no tienen una mentalidad tan técnica.


3

REST es un estilo de arquitectura para diseñar aplicaciones en red. La idea es que, en lugar de utilizar mecanismos complejos como CORBA, RPC o SOAP para conectarse entre máquinas, se use HTTP simple para hacer llamadas entre máquinas.

En muchos sentidos, la propia World Wide Web, basada en HTTP, puede verse como una arquitectura basada en REST. Las aplicaciones RESTful utilizan solicitudes HTTP para publicar datos (crear y / o actualizar), leer datos (por ejemplo, realizar consultas) y eliminar datos. Por lo tanto, REST usa HTTP para las cuatro operaciones CRUD (Crear / Leer / Actualizar / Eliminar).

REST es una alternativa ligera a mecanismos como RPC (Llamadas de procedimiento remoto) y Servicios web (SOAP, WSDL, et al.). Más adelante, veremos cuánto más simple es REST.

A pesar de ser simple, REST tiene todas las funciones; Básicamente, no hay nada que pueda hacer en los servicios web que no se pueda hacer con una arquitectura RESTful. REST no es un "estándar". Nunca habrá una recomendación del W3C para REST, por ejemplo. Y si bien existen marcos de programación REST, trabajar con REST es tan simple que a menudo puede "crear el suyo" con funciones de biblioteca estándar en lenguajes como Perl, Java o C #.


" En muchos sentidos, la propia World Wide Web, basada en HTTP, puede verse como una arquitectura basada en REST. Las aplicaciones RESTful usan solicitudes HTTP para publicar datos (crear y / o actualizar), leer datos (por ejemplo, hacer consultas), y eliminar datos. Por lo tanto, REST utiliza HTTP para las cuatro operaciones CRUD (Crear / Leer / Actualizar / Eliminar). "Este es otro gran ejemplo práctico para mí para sacar de esta publicación. Gracias.
Chris22
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.