¿Cuándo es apropiado hacer cálculos en el front-end?

21

Mi equipo está desarrollando una aplicación de finanzas basada en la WEB y hubo una pequeña discusión con un colega sobre dónde guardar los cálculos, ¿solo en el back-end o también en el front-end?

Breve explicación: Estamos utilizando Java (ZK, Spring) para front-end y Progress 4gl para back-end. Los cálculos que involucran datos matemáticos y datos de la base de datos se mantienen en el back-end, por lo que no estoy hablando de ellos. Estoy hablando de la situación en la que el usuario ingresa el valor X, luego se agrega al valor Y (se muestra en la pantalla) y el resultado se muestra en el campo Z. Quiero decir, operaciones jQuery-ish puras y simples.

Entonces, ¿cuál sería la mejor práctica aquí:

1) ¿Agregar valores con JavaScript que ahorra al ir al back-end y al back y luego validarlos en el back-end "al guardar"?

2) Mantenga toda la lógica de negocios en el mismo lugar, ¿por lo tanto, lleve los valores al back-end y haga los cálculos allí?

3) Haz los cálculos en el front-end; luego enviar datos al back-end, validarlos allí, hacer los cálculos nuevamente y solo si los resultados son válidos e iguales, ¿mostrarlos al usuario?

4) ¿Algo más?

Nota: Hacemos una validación básica en Java, pero la mayor parte todavía está en el back-end como toda la otra lógica de negocios.

El aumento de los datos que se enviarían recalculando todo en un back-end no sería un problema (tamaño XML pequeño; los servidores y el ancho de banda soportarían la mayor cantidad de operaciones realizadas por los usuarios).

IgnasK
fuente
1
Regla de oro: cuando usa un lenguaje fuertemente tipado.
Den
1
Las pruebas unitarias automatizadas serán más fáciles si toda la lógica está en el back-end. Si el 90% tiene que ser el back-end y el 10% puede estar en el back-end, entonces pondría el 100% en el back-end.
Ian
3
@Ian: también puede hacer pruebas unitarias automatizadas para códigos front-end si estructura bien su código.
Lie Ryan
1
Regla de oro: siempre que pueda salirse con la suya.
Ricitos de oro
3
Regla general: suponga que el usuario está pirateando su JavaScript y haciendo sus propios cálculos. Desde el punto de vista de la seguridad, los cálculos deben hacerse en el back-end. También puede hacer ambas cosas: JS puede proporcionar comentarios más rápidos, pero los cálculos que realmente cuentan se realizan en el servidor.

Respuestas:

36

Como siempre, tales decisiones implican una compensación entre diferentes objetivos, algunos de los cuales entran en conflicto entre sí.

  • La eficiencia sugeriría que realice cálculos en el front-end, tanto porque de esa manera la computadora del usuario usa más energía y su servidor usa menos, como porque el usuario ve comentarios más rápidos, lo que mejora la experiencia del usuario.

  • La seguridad exige que cualquier operación de cambio de estado no pueda confiar en que los datos se verifiquen o computen en la computadora cliente, porque la computadora cliente puede estar bajo el control de un atacante malintencionado. Por lo tanto, debe validar todo lo que provenga de fuentes no confiables del lado del servidor.

  • La eficiencia de la programación y el mantenimiento sugieren que no debe hacer el mismo cálculo dos veces debido al esfuerzo desperdiciado.

Superficialmente, esto suena como si todo tuviera que hacerse del lado del servidor, pero ese no es siempre el caso. Si puede mantener fácilmente el código duplicado (por ejemplo, generando automáticamente un validador de JavaScript desde su validador de Java del lado del servidor), entonces repetir el cálculo puede ser una buena solución. Si los datos involucrados no son importantes, por ejemplo, si el usuario solo puede engañar a sí mismo y no a usted si manipula los valores, entonces la validación del lado del servidor no es necesaria. Si su tiempo de respuesta está dominado por cuellos de botella completamente diferentes para que un retraso de ida y vuelta no sea perceptible, entonces las consideraciones de UX no son decisivas, etc. Por lo tanto, debe considerar cuán fuerte es cada una de estas presiones en su situación y decidir en consecuencia .

Kilian Foth
fuente
44
Me gustaría agregar que eso Programming efficiency and maintainability suggests that you shouldn't do the same computation twice because of the wasted effort.no es correcto porque [1] La validación en el front-end puede proporcionar comentarios rápidos al usuario para hacer correcciones si es necesario. [2] La validación en el back-end no es tan receptiva y, por lo tanto, no proporciona al usuario la mejor oportunidad para hacer correcciones. El usuario debería esperar y rehacer más trabajo. Así que creo que las dos validaciones no son exactamente las mismas.
InformadoA
99
Eso no es lo que quería llegar al otro lado - mantenibilidad hace implicaría "no repita a sí mismo", y de acuerdo con este principio la repetición es sin duda una mala. Si no hubiera otras consideraciones, no debería hacerlo. El hecho de que es, sin embargo, a menudo una buena idea es porque no son otras consideraciones que contradicen este principio, es decir, mayor facilidad de uso a través de respuesta rápida.
Kilian Foth
@randomA Está aplicando mal ese principio, si quiere decir que algo que debe validarse en el servidor solo debe calcularse en el servidor, porque si el "valor validado del servidor" (o cualquier cosa que dependa de él) se devuelva al cliente en algún momento enviado de vuelta al servidor, debe validarlo de nuevo de todos modos , inútil. O bien, necesita algún sistema de referencias seguras, que puede ser aún más ineficiente. Diría que si puede hacer un cálculo en el cliente, hágalo en el cliente , pero también nunca confíe en lo que el cliente le dice .
Ricitos de oro
@goldilocks Lo que dijiste en negrita también es lo que estoy de acuerdo, tienes que validar todo en el back-end. Mi punto era que: la validación en el front-end es más receptiva, por lo que no es exactamente lo mismo que la validación en el back-end.
Informado A
13

Hay fuertes razones para hacer cálculos en el backend

  • La lógica empresarial no pertenece a la capa de presentación
  • La lógica empresarial en JavaScript representa una amenaza
  • Asume que hay una relación de un solo front-end -> one-back-end que no siempre es cierto , los back-end deben considerarse como capaces o que sirven a más de una aplicación front-end, por lo que no puede asumir nada.
  • Si los cálculos usan una gran cantidad de datos, no sería eficiente mantenerlos en el front-end
  • Si los cálculos usan la base de datos, no podrá replicarla en el front end

Mi recomendación

  • Haga que la base de datos aplique la mayor cantidad posible de reglas comerciales en el modelo, incluidas claves externas, claves principales, restricciones de comprobación y desencadenantes
  • Haga que la capa empresarial arroje excepciones cuando no se cumplan las reglas comerciales (ya sea porque la base de datos devolvió un error o porque la capa comercial misma validó los datos)
  • Si y solo si el tiempo de respuesta es inaceptable, realice validaciones o preprocesos utilizando Ajax (el trabajo no se realizará realmente en JavaScript, se realizará en el backend sin tener que volver a cargar la página)
  • Puede hacer una validación simple en JavaScript, como no permitir un valor vacío, o valores que sean demasiado largos o fuera de rango (para este último, es posible que desee generar los rangos en el back-end)
Tulains Córdova
fuente
2
¡El problema con hacer que la base de datos haga cumplir las reglas comerciales es informar violaciones al front-end! Si el front-end aplica las reglas comerciales, puede enviar rápidamente mensajes de error significativos al usuario. Si el back-end lo hace, hay mucho tráfico torpe de dos vías entre el front-end y el back-end ya que los errores se informan uno por uno.
James Anderson el
@JamesAnderson Ya no hay "el front-end". Puede haber varios front-end para la misma base de datos, o varias bases de datos para varios front-end. Además, tener el back-end hace cumplir las reglas comerciales no significa que el front-end tenga prohibido hacerlo. Lo destaqué en el segundo punto.
Tulains Córdova