¿Qué tiene de malo que un punto final devuelva HTML en lugar de datos JSON?


77

Cuando comencé a aprender PHP (hace unos 5 o 6 años) aprendí sobre Ajax y pasé por "las fases":

  1. Tu servidor devuelve datos HTML y los pones dentro del innerHTML de un DOM
  2. Aprenderá sobre los formatos de transferencia de datos como XML (y dirá "oooh, para eso ES para lo que se usa") y luego JSON.
  3. Devuelve JSON y crea su interfaz de usuario utilizando el código JavaScript de vainilla
  4. Te mudas a jQuery
  5. Aprenderá sobre API, encabezados, códigos de estado HTTP, REST , CORS y Bootstrap
  6. Aprende los marcos de SPA y frontend ( React , Vue.js y AngularJS ) y el estándar JSON API.
  7. Recibe un código heredado de la empresa y, al inspeccionarlo, descubre que hacen lo que se describe en el paso 1.

Mientras trabajaba con esta base de código heredada, ni siquiera consideré que podría devolver HTML (quiero decir, somos profesionales ahora, ¿verdad?), Así que tuve dificultades para buscar el punto final JSON que devolvía los datos que las llamadas de Ajax pueblan. No fue hasta que le pregunté al "programador" que me dijo que estaba devolviendo HTML y que se estaba agregando directamente al DOM con innerHTML.

Por supuesto, esto fue difícil de aceptar. Comencé a pensar en formas de refactorizar esto en los puntos finales JSON, pensando en la prueba unitaria de los puntos finales, etc. Sin embargo, esta base de código no tiene pruebas. Ni uno solo. Y tiene más de 200 mil líneas. Por supuesto, una de mis tareas incluye proponer enfoques para probar todo, pero por el momento todavía no lo estamos abordando.

Así que no estoy en ninguna parte, en un rincón, preguntándome: si no tenemos pruebas de ningún tipo, entonces no tenemos una razón particular para crear este punto final JSON (ya que no es "reutilizable": literalmente devuelve datos que solo se ajustan a esa parte del aplicación, pero creo que esto ya estaba implícito ya que ... devuelve datos HTML).

¿Qué tiene de malo exactamente hacer esto?



3
También relacionado: stackoverflow.com/questions/1284381/… <- Una muy buena respuesta en SO.
Machado

73
¿Un servidor que utiliza el protocolo de transferencia de hipertexto que devuelve hipertexto? ¡El horror!
Andy

3
@Andy Para ser sincero, en realidad se trata del Protocolo genérico de transferencia de mensajes: nada de eso es específico para transferir hipertexto, a diferencia del FTP, que habla mucho sobre cosas específicas de archivos y directorios.
Joker_vD

44
@Joker_vD Nunca he oído hablar de un protocolo llamado GMTP. Si bien las cosas han evolucionado y puedes enviar otros tipos de contenido a través de HTTP, no fue la intención original. Mi punto es que solo porque puede enviar otro contenido además de HyperText usando HTTP, parece una tontería sugerir que ya no es válido usarlo para su propósito original.
Andy

Respuestas:


114

¿Qué tiene de malo que un punto final devuelva HTML en lugar de datos JSON?

Nada en realidad. Cada aplicación tiene requisitos diferentes, y puede ser que su aplicación no esté diseñada para ser un SPA.

Puede ser que estos hermosos marcos que usted citó (Angular, Vue, React, etc.) no estuvieran disponibles en el momento del desarrollo, o no fueran cosas empresariales "aprobadas" para ser utilizadas en su organización.

Te diré esto: un punto final que devuelve HTML reduce tu dependencia de las bibliotecas de JavaScript y reduce la carga en el navegador del usuario ya que no necesitará interpretar / ejecutar código JS para crear objetos DOM: el HTML ya está allí, solo es cuestión de analizar los elementos y representarlos. Por supuesto, esto significa que estamos hablando de una cantidad razonable de datos. 10 megabytes de datos HTML no son razonables.

Pero dado que no hay nada de malo en devolver HTML, lo que está perdiendo al no usar JSON / XML es básicamente la posibilidad de usar su punto final como API. Y aquí está la pregunta más importante: ¿realmente necesita ser una API?

Relacionado: ¿Está bien devolver HTML desde una API JSON?


44
Daría un paso atrás antes de decir que es "simplemente preferencia". Hay algunas decisiones "importantes" que debe tomar: ¿Es una API o no? ¿Tengo las bibliotecas adecuadas para trabajar con esto como datos JSON en el cliente, qué tipo de cliente admitiré (navegadores sin Javascript, para ejemplo), qué volumen frente a tiempo de CPU tengo disponible para usar, qué estrategia aprovecharán mejor mis programadores, etc., etc., etc.
Machado

77
"No será necesario interpretar el código JS para crear objetos DOM: los objetos DOM ya están allí, solo es cuestión de representarlos", bueno, el HTML ya está allí (una vez que se ha llegado por cable). El navegador tiene que analizar el HTML y crear los objetos DOM a partir de él.
Paul D. Waite

77
No hay razón para que HTML no pueda actuar como una API. Cero. Ninguna. De hecho, HAL + JSON y HAL + XML tienen un parecido sorprendente con HTML. Aquí hay una excelente charla sobre REST. La parte relevante sobre la devolución de HTML desde un punto final está cerca del final. youtu.be/pspy1H6A3FM Personalmente, hago que todos mis puntos finales devuelvan tanto json como HTML. Si está escribiendo servicios reconocibles, hace que sea realmente fácil navegar en ... jadear ... un navegador.
RubberDuck

44
¿Porque es una perra completa extraer los datos que realmente te interesan para tratar de usarlos de alguna manera nueva?
DeadMG

44
¿Sirve HTML sobre HTTP? ¿Que es esto? ¿Una página web?
Ant P

50

JSON y HTML cumplen dos propósitos semánticos diferentes.

Si está completando una página web con datos, use JSON. Si está creando una página web a partir de partes de páginas web, use HTML.

Puede parecer que son lo mismo, pero no lo son en absoluto. Por un lado, cuando está creando una parte de una página web utilizando HTML devuelto por el servidor, está trabajando en el lado del servidor. Cuando vincula datos a una página web, está trabajando en el lado del cliente.

Además, debe tener cuidado con HTML para no vincularse con una página específica. El objetivo de renderizar páginas parciales de esta manera es que los parciales sean reutilizables, y si hace que el parcial sea demasiado específico, no se compondrá en otras páginas. JSON no tiene este problema, porque son solo datos, no la estructura de la página web.


1
"Por un lado, cuando está creando una parte de una página web usando HTML, está trabajando en el lado del servidor". ¿Por qué? No veo ninguna razón por la cual este debería ser el caso. Obviamente, solo es cierto para la carga de la página inicial y podría decirse que ni siquiera entonces, ya que el cliente puede realizar las solicitudes de los datos que necesita.
DeadMG

3
@DeadMG Debería decir "cuando está creando una parte de una página web usando HTML devuelto por el servidor" (en lugar de usar JSON devuelto por el servidor)
user253751

De hecho, pero dado que hay poca motivación para que ese sea el caso, no veo el punto.
DeadMG

66
@DeadMG ¿Poca motivación para lo que alguna vez será el caso? ¿Para que el servidor devuelva HTML? Eso es literalmente de lo que se trata toda esta pregunta SE.
user253751

La pregunta es sobre si debe devolver HTML o no. Está claro que la respuesta inicial debe ser HTML, pero no hay una razón obvia por la cual cualquier otra API deba devolver HTML.
DeadMG

22

El principal problema es que une estrechamente el servidor con el cliente, que debe conocer la estructura HTML. También hace que los puntos finales sean más difíciles de reutilizar de nuevas formas o nuevas aplicaciones.

Devolver datos simples y dejar que el cliente los procese disminuye el acoplamiento y aumenta la flexibilidad y la capacidad de prueba: puede ejecutar pruebas unitarias en el cliente para obtener datos simulados y ejecutar pruebas unitarias en el servidor para probar los datos deseados.


11
HTML puede hacerse razonablemente genérico. Puede devolver una lista con viñetas, por ejemplo, y rellenarla en un div, donde estará sujeta al estilo del CSS prevaleciente.
Robert Harvey

10
Eso no es tan útil si necesito meterlo en un lapso esta vez. O renderízalo en otra aplicación que no esté renderizada en HTML.
DeadMG

2
Reformularía como siempre estará componiendo HTML, y la forma de ese HTML siempre debe ser completamente consistente en todos los usos, lo cual no es una garantía muy útil. Por ejemplo, en nuestra aplicación tenemos listas, pero en realidad no las usamos uly en su lilugar cambiamos para hacer que cada una sea un div(no recuerdo por qué). Hubiera sido complicado si el servidor devolviera un montón de HTML con ulsy lis en él.
DeadMG

2
Parece inútil obtener la garantía en primer lugar cuando solo puede devolver los datos y dejar que el cliente lo procese como HTML como mejor le parezca (si es que lo va a hacer)
DeadMG

1
El único escenario que puedo ver en el que sería preferible devolver HTML es si el cliente no tiene suficientes recursos para hacer el renderizado.
DeadMG

14

Creo que lo tienes un poco al revés. Tu dices:

no tenemos ninguna prueba, por lo que no tenemos ninguna razón particular para crear este punto final JSON

Una razón para usar un punto final adecuado sería para que pueda probarlo. Yo diría que no tener exámenes es una muy buena razón para comenzar a escribir algunos. Es decir, si hay alguna lógica que sea adecuada para probar.

200k líneas de código es mucho para refactorizar y probablemente sean difíciles de mantener. Romper algunos puntos finales y probarlos podría ser un buen lugar para comenzar.

Otra razón podría ser separar el servidor del cliente. Si, en un futuro lejano, el diseño o el diseño de la aplicación cambia, es más fácil trabajar con un formato de datos adecuado que la salida HTML. En un mundo ideal, solo tendría que cambiar el cliente y no tocar el servidor en absoluto.


El punto sobre los cambios de diseño suena más como una necesidad de separar plantillas de los datos subyacentes, pero no hay razón para que esas plantillas tengan que estar en el cliente. De hecho, hay muchas razones para que no lo sean, por ejemplo, no puede decidir ocultar datos del cliente si su representación está en el cliente. Los parciales HTML se pueden volver a pelar muy bien si los genera el mismo sistema de plantillas que las páginas HTML completas.
IMSoP

6

Hay 3 formas (¿al menos?) Para construir una página web:

  • Genere todo el lado del servidor de páginas.
  • Devuelva una página básica del servidor más código (JavaScript), y haga que la página obtenga sus datos y los procese en el lado del cliente HTML.
  • Devuelva una página parcial más código, y haga que el código recupere los bloques de HTML previamente renderizados que puede colocar en la página.

El primero está bien. El segundo también está bien. Es el último el problema.

La razón es simple: ahora ha dividido la construcción de la página HTML en partes completamente desconectadas. El problema es de mantenimiento. Ahora tiene dos entidades separadas a cargo de administrar los detalles de la IU. Por lo tanto, debe mantener sincronizados CSS y otros detalles similares entre las dos piezas separadas. ¿Cambiaste el ancho de la barra lateral? Excelente. Ahora, el fragmento HTML que regresa causa desplazamiento horizontal porque sus supuestos sobre el ancho de la barra lateral ya no se mantienen. ¿Cambiaste el color de fondo para ese bloque? Genial, ahora el color de fuente de su fragmento HTML choca porque asumió un color de fondo diferente y alguien olvidó probar ese punto final.

El punto es que ahora ha dividido el conocimiento que debe centralizarse en un solo lugar (es decir, la lógica de presentación), y esto hace que sea más difícil asegurarse de que todas las piezas encajen correctamente. Al usar una API JSON, en su lugar, puede mantener toda esa lógica solo en el front-end, o puede mantenerlo todo en las plantillas del lado del servidor si, para empezar, procesa sus datos en HTML. Se trata de mantener el conocimiento / lógica de la presentación en un solo lugar, para que se pueda administrar de manera consistente y como parte de un solo proceso. HTML / CSS / JS es lo suficientemente difícil de mantener recto sin dividirlo en muchas piezas pequeñas.

Las API JSON también tienen el beneficio adicional de hacer que los datos estén disponibles de forma completamente independiente de la lógica de presentación. Esto permite que varios presentadores diferentes , como una aplicación móvil y una página web, consuman los mismos datos. En particular, permite consumir los datos sin un navegador (como aplicaciones móviles o trabajos cron nocturnos); Es posible que estos consumidores ni siquiera puedan analizar HTML. (Esto, por supuesto, se basa necesariamente en una situación en la que los datos son los mismos entre los diferentes consumidores, o uno puede usar un subconjunto del otro). Sin embargo, si necesita esta capacidad depende de los requisitos de su aplicación particular, mientras administra su presentación La lógica es necesaria independientemente. Sin embargo, diré que si lo implementa por adelantado, estará mejor preparado para el crecimiento futuro.


2
De hecho, creo que evitar la lógica de visualización duplicada puede ser una buena razón para representar fragmentos de página HTML: si representa parte de la página en el servidor (por ejemplo, el encabezado y el diseño básico), genera otras partes basadas en datos JSON en el cliente, usted tener dos conjuntos diferentes de plantillas. La representación de parciales en el servidor mueve esta lógica de regreso a su capa de presentación central, que puede usar la misma plantilla para representar un componente individual como lo haría si estuviera ensamblando estáticamente toda la página.
IMSoP

1
eres el único que menciona el móvil, quiero darte mil votos a favor para eso
Lovis

1
@IMSoP Si necesita una página dinámica , debe tener una lógica de front-end. Si aún renderiza fragmentos del lado del servidor, ahora debe asegurarse de que los supuestos del front-end coincidan con las condiciones previas del servidor que construye los fragmentos. No puedes romper esa dependencia. Mantener ese conocimiento sincronizado es más difícil si se divide en sistemas completamente divididos. Si solo renderiza en el front-end, esos supuestos están centralizados. Creo que también evitaría mezclar un front-end dinámico con un estado inicial en una plantilla del lado del servidor; Una "rutina de arranque" para iniciar el front-end es más simple.
jpmc26

4

Diría que no hay nada de malo en que el servidor devuelva un fragmento HTML y la UI lo asigne a .innerHTML de algún elemento. Esta es, en mi opinión, la forma más fácil de desarrollar código JavaScript asincrónico. El beneficio es que se hace lo menos posible con JavaScript y se hace lo más posible en un entorno de fondo controlado. Recuerde que la compatibilidad con JavaScript en los navegadores varía, pero su back-end siempre tiene la misma versión de los componentes de back-end, lo que significa que hacer todo lo posible en el back-end significará la menor cantidad posible de incompatibilidades de versiones.

Ahora, a veces quieres más que solo un fragmento HTML. Por ejemplo, un código de estado y un fragmento HTML. Luego puede usar un objeto JSON que tiene dos miembros, statusCode y HTML, de los cuales el segundo puede asignarse a .innerHTML de algún elemento después de verificar el statusCode. Por lo tanto, el uso de JSON y el uso de innerHTML no son en modo alguno enfoques exclusivos alternativos; Se pueden usar juntos.

Al usar JSON, incluso puede tener múltiples fragmentos HTML en la misma respuesta que se asignan al .innerHTML de varios elementos.

En resumen: use .innerHTML. Hace que su código sea compatible con tantas versiones de navegador como sea posible. Si necesita más, use JSON y .innerHTML juntos. Evita XML.


4

No hay nada malo en principio . La pregunta es: ¿Qué quieres lograr?

JSON es perfecto para transmitir datos. Si envía HTML en su lugar y espera que el cliente extraiga los datos del HTML, eso es basura.

Por otro lado, si desea transmitir HMTL que se representará como HTML, envíelo como HTML, en lugar de empaquetar el HTML en una cadena, convertir la cadena en JSON, transmitir JSON, decodificarlo en el otro lado , obtener una cadena y extraer el HTML de la cadena.

Y ayer me encontré con un código que colocaba dos elementos en una matriz, convertía la matriz en JSON, ponía la JSON en una cadena, ponía la cadena dentro de una matriz, convertía toda la matriz en JSON, la enviaba al cliente, que decodificaba el JSON, obtuvo una matriz que contiene una cadena, tomó la cadena, extrajo el JSON de la cadena, decodificó el JSON y obtuvo una matriz con dos elementos. No hagas eso.


+1 exactamente. La primera pregunta es, ¿qué necesitas recibir? Sería poco incorrecto que un punto final devuelva anuncios de barra lateral como un poco de HTML, o tal vez un pie de página, o elementos similares.
SQB

3

Todo esto depende del propósito de la API, pero en general lo que describe es una violación bastante fuerte de la separación de preocupaciones :

En una aplicación moderna, el código API debe ser responsable de los datos, y el código del cliente debe ser responsable de la presentación.

Cuando su API devuelve HTML, está estrechamente acoplando sus datos y presentación. Cuando la API devuelve HTML, lo único que puede hacer (fácilmente) con ese HTML es mostrarlo como parte de una página más grande. Desde un ángulo diferente, lo único para lo que la API es buena es proporcionarle a su página HTML. Además, ha extendido su HTML a través del código del cliente y del servidor. Esto puede hacer que el mantenimiento sea un dolor de cabeza.

Si su API devuelve JSON, o alguna otra forma de datos puros, se vuelve mucho más útil. La aplicación existente aún puede consumir esos datos y presentarlos adecuadamente. Ahora, sin embargo, otras cosas pueden usar la API para acceder a los mismos datos. Nuevamente, también, el mantenimiento es más fácil: todo el HTML reside en un solo lugar, por lo que si desea cambiar el estilo de todo el sitio, no necesita cambiar su API.


55
"En una aplicación moderna, el código API debería ser responsable de los datos, y el código del cliente debería ser responsable de la presentación". ¿Por qué debería ser este siempre el caso? Estoy de acuerdo en que este es un patrón común y que facilita ciertas cosas, pero no veo ninguna razón para elevarlo al nivel de "debería" ... Es una decisión que debe tomarse caso por caso, y ciertamente hay razones por las cuales, en algunas situaciones, es posible que desee tomar una decisión diferente.
Jules

@Jules porque si tiene una API y un cliente, tener ambos a cargo de la representación es una violación de la separación de preocupaciones. (Ahora, no necesariamente tiene una API y un cliente. Puede tener un solo componente y hacer que haga toda la presentación. Pero entonces no tiene una API)
njzk2

@ njzk2 El hecho de que una API entregue datos HTML no significa que los haya procesado. Puede tratar el HTML como un blob y almacenarlo en una base de datos, por ejemplo. Además, es posible que se requiera algo de representación en el servidor en lugar del cliente (por ejemplo, proporcionar páginas estáticas para los motores de búsqueda), por lo que reutilizar esa capacidad podría verse como una eliminación de la duplicación.
Jules

1
Además, es completamente posible producir un cliente y un par de API donde todo el procesamiento se produce en el servidor y el cliente simplemente conecta HTML entregado en ranuras predefinidas en su DOM. Jquery tiene un módulo completo dedicado a este tipo de cliente, lo que me sugiere que deben ser razonablemente comunes.
Jules

1
@Jules muchas cosas son razonablemente comunes, esa no es una razón por la que son razonables.
njzk2

2

HTML está vinculado a un diseño y uso específicos.

Con HTML, si desea cambiar el diseño de la página, debe cambiar cómo se genera el html por la llamada al servidor. Por lo general, eso requiere un programador de fondo. Ahora tiene programadores back-end, que por definición no son sus mejores escritores html, manejando estas actualizaciones.

Con JSON, si el diseño de la página cambia, la llamada al servidor JSON existente no necesariamente tiene que cambiar en absoluto. En cambio, su desarrollador front-end, o incluso el diseñador, actualiza la plantilla para producir los diferentes HTML que desea a partir de los mismos datos básicos.

Además, el JSON puede convertirse en la base de otros servicios. Es posible que tenga diferentes roles que necesiten ver los mismos datos básicos de diferentes maneras. Por ejemplo, puede tener un sitio web del cliente que muestre datos sobre un producto en una página de pedido, y una página de ventas internas para representantes que muestre los mismos datos en un diseño muy diferente, tal vez junto con otra información no disponible para clientes generales. Con JSON, se puede usar la misma llamada al servidor en ambas vistas.

Finalmente, JSON puede escalar mejor. En los últimos años, nos hemos pasado de la raya con los marcos javascript del lado del cliente. Creo que es hora de dar un paso atrás y comenzar a pensar qué javascript estamos usando y cómo afecta el rendimiento del navegador ... especialmente en dispositivos móviles. Dicho esto, si está ejecutando un sitio lo suficientemente grande como para requerir una granja de servidores o un clúster, en lugar de un solo servidor, JSON puede escalar mejor. Los usuarios le darán tiempo de procesamiento en sus navegadores de forma gratuita, y si aprovecha esto, puede reducir la carga del servidor en una implementación grande. JSON también usa menos ancho de banda, así que de nuevo, si eres lo suficientemente grandey usarlo adecuadamente, JSON es mucho más barato. Por supuesto, también puede escalar peor, si termina alimentando bibliotecas de 40 KB para analizar 2 KB de datos en 7 KB de html, así que de nuevo: vale la pena estar al tanto de lo que está haciendo. Pero el potencial está ahí para que JSON mejore el rendimiento y los costos.


1

No hay nada de malo en tal punto final si cumple con sus requisitos. Si se requiere escupir html para que un consumidor conocido pueda analizarlo de manera efectiva, claro, ¿por qué no?

El problema es que, para el caso general, desea que sus puntos finales escupan una carga útil que esté bien formada y sea efectivamente analizable por un analizador estándar. Y por efectivamente analizable, quiero decir, analizable de manera declarativa.

Si su cliente se ve obligado a leer la carga útil y extraer bits de información abierta de él con bucles y sentencias if, entonces no es efectivamente analizable. Y HTML, siendo así, está muy perdonado al no requerir que esté bien formado.

Ahora, si te aseguras de que tu html es compatible con xml, entonces eres oro.

Dicho esto, tengo un problema importante con esto:

Te diré esto: un punto final que devuelve HTML reduce tu dependencia de las bibliotecas de JavaScript y reduce la carga en el navegador del usuario ya que no necesitará interpretar / ejecutar código JS para crear objetos DOM: el HTML ya está allí, solo es cuestión de analizar los elementos y representarlos. Por supuesto, esto significa que estamos hablando de una cantidad razonable de datos. 10 megabytes de datos HTML no son razonables.

Esa es una mala idea, no importa cómo la cortes. Décadas de experiencia industrial colectiva nos han demostrado que, en general, es una buena idea separar los datos (o modelo) de su visualización (o vista).

Aquí está combinando los dos con el fin de ejecutar rápidamente el código JS. Y eso es una micro optimización.

Nunca he visto esto como una buena idea, excepto en sistemas muy triviales.

Mi consejo? No lo hagas HC SVNT DRACONES , YMMV, etc.


0

JSON es solo una presentación textual de datos estructurados. Un cliente, naturalmente, necesita tener un analizador para procesar datos, pero prácticamente todos los idiomas tienen funciones de analizador JSON. Es mucho más eficiente usar el analizador JSON que usar el analizador HTML. Se necesita poca huella. No es así con un analizador HTML.

En PHP, solo usa json_encode($data)y depende del cliente del otro lado analizarlo. Y cuando obtiene datos JSON de un servicio web, simplemente usa $data=json_decode($response)y puede decidir cómo usar los datos como lo haría con las variables.

Supongamos que desarrolla una aplicación para un dispositivo móvil, ¿por qué necesita el formato HTML cuando las aplicaciones móviles rara vez usan el navegador web para analizar datos? Muchas aplicaciones móviles usan JSON (formato más común) para intercambiar datos.

Teniendo en cuenta que los móviles suelen estar en planes medidos, ¿por qué desea utilizar HTML que requiere mucho más ancho de banda que JSON?

¿Por qué usar HMTL cuando HTML tiene un vocabulario limitado y JSON puede definir datos? {"person_name":"Jeff Doe"}es más informativo de lo que HTML puede proporcionar sobre sus datos, ya que solo define la estructura de los analizadores HTML, no define los datos.

JSON no tiene nada que ver con HTTP. Puedes poner JSON en un archivo. Puede usarlo para configuraciones. Composer usa JSON. También puede usarlo para guardar variables simples en archivos.


0

Es difícil clasificar un bien o un mal. En mi opinión, las preguntas que haré son: "¿ debería " o " puede hacer con menos? ".

Cada punto final debe esforzarse por comunicarse con el menor contenido posible. La relación señal / ruido suele ser códigos HTTP <JSON <XHTML. En la mayoría de las situaciones, es bueno elegir el protocolo menos ruidoso.

Difiero en el punto sobre la carga del navegador del cliente por @machado, ya que con los navegadores modernos esto no es un problema. La mayoría de ellos están equipados para manejar códigos HTTP y respuestas JSON bastante bien. Y aunque no tiene pruebas en este momento, el mantenimiento a largo plazo de un protocolo menos ruidoso sería más barato que el anterior.

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.