Mantenga la demostración del artículo cuando una API de terceros muera
Cuatro años después, mi presentación «Envíe la cabeza sin cabeza con WordPress REST API» El artículo finalmente dejó de funcionar.
Este artículo incluye CodePen Increddings, que demuestran cómo usar el punto final API REST del complemento de formulario de WordPress popular para atrapar y mostrar errores de validación y enviar comentarios al construir un front-end totalmente personalizado. La pluma se basa en el sitio web de WordPress que ejecuto en segundo plano. Pero durante la migración de la infraestructura forzada, el sitio no se transfirió correctamente, y peor aún, perdí el acceso a la cuenta.
Por supuesto que yo Poder Se ha contactado el soporte o se ha restaurado la copia de seguridad en otro lugar. Pero la situación me hace dudar: ¿Qué pasaría si no fuera por WordPress? ¿Qué debo hacer si se trata de un servicio de terceros que no puedo anular o arreglar? ¿Hay alguna forma de construir demostraciones que no se rompan cuando falla el servicio del que dependen? ¿Cómo nos aseguramos de que las presentaciones educativas puedan estar disponibles el mayor tiempo posible?
¿O es inevitable? ¿La demostración está condenada a romperse como todo lo demás en la web?
Similar a las pruebas de software
Aquellos que escriben pruebas de código han luchado durante mucho tiempo con problemas similares, aunque con diferentes composiciones. Core, el problema es el mismo. Las dependencias, especialmente las de terceros, están fuera de control.
No es sorprendente que la forma más confiable de eliminar los problemas de dependencia externos es eliminar los servicios externos por completo de la ecuación, cancelándolos efectivamente de ella. Por supuesto, cómo se hace esto y si siempre es posible depende del contexto.
Sucede que las técnicas para tratar con las dependencias son igualmente útiles al hacer que la presentación sea más resistente.
Para mantener lo concreto, tomaré la demostración de CodePen mencionada como ejemplo. Pero en muchos otros casos, el mismo enfoque funciona.
Dependencias de API de REST desacopladas
A pesar de muchas estrategias y trucos, las dos formas más comunes de romper la dependencia de la API REST son:
- Burlarse de las llamadas HTTP en código en lugar de ejecutar solicitudes de red reales, pero devolver una respuesta fija
- Use un servidor API simulado como un sustituto de un servicio real y proporcione respuestas predefinidas de manera similar
Hay compensaciones para ambos, pero echemos un vistazo más tarde.
Responder con un interceptor
Marcos de prueba modernos, ya sea para pruebas de unión o de extremo a extremo, p. Sí o dramaturgoproporciona funciones de simulación incorporadas.
Sin embargo, no necesariamente los necesitamos, y de todos modos no podemos usarlos en la pluma. En cambio, podemos parcharlo Extracto API Interceptar la solicitud y devolver la respuesta simulada. Con el parche de mono, al cambiar el código fuente original no es factible, podemos introducir un nuevo comportamiento sobrescribiendo las características existentes.
La implementación se ve así:
const fetchWPFormsRestApiInterceptor = (fetch) => async (
resource,
options = {}
) => {
// To make sure we are dealing with the data we expect
if (typeof resource !== "string" || !(options.body instanceof FormData)) {
return fetch(resource, options);
}
if (resource.match(/wp-json\/contact-form-7/)) {
return contactForm7Response(options.body);
}
if (resource.match(/wp-json\/gf/)) {
return gravityFormsResponse(options.body);
}
return fetch(resource, options);
};
window.fetch = fetchWPFormsRestApiInterceptor(window.fetch);
Anulamos el valor predeterminado fetch Con nuestra propia versión, se puede agregar una lógica personalizada a condiciones específicas, de lo contrario, la solicitud se aprobará sin cambios.
Reemplazar la función, fetchWPFormsRestApiInterceptorcomo un interceptor. Los interceptores simplemente modifican el patrón de solicitud o respuesta basado en ciertas condiciones.
Muchas bibliotecas HTTP, como las que alguna vez fueron muy populares ejeproporcionando adición de API conveniente Interceptador No recurra a parches de mono y se debe usar con precaución. Es muy fácil introducir errores sutiles o crear conflictos al administrar múltiples alternativas.
Devolver una respuesta falsa cuando el interceptor está en su lugar es tan simple como llamar a un método JSON estático Response Objetivo:
const contactForm7Response = (formData) => {
const body = {}
return Response.json(body);
};
Dependiendo del requisito, la respuesta puede ser de texto sin formato a Blob o ArrayBuffer. También puede especificar un código de estado personalizado e incluir títulos adicionales.
Para las demostraciones de CodePen, la respuesta podría construirse así:
const contactForm7Response = (formData) => {
const submissionSuccess = {
into: "#",
status: "mail_sent",
message: "Thank you for your message. It has been sent.!",
posted_data_hash: "d52f9f9de995287195409fe6dcde0c50"
};
const submissionValidationFailed = {
into: "#",
status: "validation_failed",
message:
"One or more fields have an error. Please check and try again.",
posted_data_hash: "",
invalid_fields: ()
};
if (!formData.get("somebodys-name")) {
submissionValidationFailed.invalid_fields.push({
into: "span.wpcf7-form-control-wrap.somebodys-name",
message: "This field is required.",
idref: null,
error_id: "-ve-somebodys-name"
});
}
// Or a more thorough way to check the validity of an email address
if (!/^(^\s@)+@(^\s@)+\.(^\s@)+$/.test(formData.get("any-email"))) {
submissionValidationFailed.invalid_fields.push({
into: "span.wpcf7-form-control-wrap.any-email",
message: "The email address entered is invalid.",
idref: null,
error_id: "-ve-any-email"
});
}
// The rest of the validations...
const body = !submissionValidationFailed.invalid_fields.length
? submissionSuccess
: submissionValidationFailed;
return Response.json(body);
};
En este punto, cualquiera fetch Llame a la coincidencia de URL wp-json/contact-form-7 Devuelva un error exitoso o de validación para las vacaciones en función de la entrada del formulario.
Ahora, comparemos esto con el método de servidor API simulado.
Servidor API de imitación sin servidor
Ejecutar un servidor API de suplantación administrada tradicional reintroduce preocupaciones sobre la disponibilidad, el mantenimiento y el costo. Incluso si la exageración sobre la funcionalidad sin servidor ya es silenciosa, podemos evitar estos problemas utilizándolos.
Y con Características de Digitalocean Ofrecer espaciosas capas libres, crear API burladas es realmente gratuita y no requiere burlarse manualmente.
Para casos de uso simples, todo se puede hacer a través del panel de control de funciones, incluida la escritura de código en el editor incorporado. Mira este video conciso de demostración para ver qué hace:
Para requisitos más complejos, la función puede ser Desarrollar e implementar localmente usar doctl (CLI de Digitalocean).
Para devolver la respuesta simulada, si Crear una característica separada Para cada punto final, podemos evitar agregar condiciones innecesarias. Afortunadamente, podemos seguir con JavaScript (Node.js), comenzando con casi la misma base que usamos contactForm7Response:
function main(event) {
const body = {};
return { body };
}
Debemos nombrar la función del controlador mainllamado cuando se llama al punto final. Esta función recibe event El objeto es su primer parámetro, incluyendo Detalles de solicitud. Una vez más, podemos devolver cualquier cosa, pero para devolver la respuesta JSON que necesitamos, es suficiente Objeto de retorno.
Podemos reutilizar el mismo código para crear la respuesta tal como está. La única diferencia es que tenemos que event Como FormData Nosotros mismos:
function main(event) {
// How do we get the FormData from the event?
const formData = new FormData();
const submissionSuccess = {
// ...
};
const submissionValidationFailed = {
// ...
};
if (!formData.get("somebodys-name")) {
submissionValidationFailed.invalid_fields.push({
// ...
});
}
// Or a more thorough way to check the validity of an email address
if (!/^(^\s@)+@(^\s@)+\.(^\s@)+$/.test(formData.get("any-email"))) {
submissionValidationFailed.invalid_fields.push({
// ...
});
}
// The rest of the validations...
const body = !submissionValidationFailed.invalid_fields.length
? submissionSuccess
: submissionValidationFailed;
return { body };
}
En lo que respecta a la conversión de datos, la funcionalidad sin servidor a menudo esperará la entrada JSON, por lo que para otros tipos de datos, se requieren pasos de análisis adicionales. Sucede que el formulario en la demostración de CodePen se presenta como multipart/form-data.
Sin ninguna biblioteca, podemos convertir multipart/form-data Hundir en uno FormData Utilizando Response Características de la API:
async function convertMultipartFormDataToFormData(data) {
const matches = data.match(/^\s*--(\S+)/);
if (!matches) {
return new FormData();
}
const boundary = matches(1);
return new Response(data, {
headers: {
"Content-Type": `multipart/form-data; boundary=${boundary}`
}
}).formData();
}
Este código se centra en extraer variables límite. Por ejemplo, al enviar un formulario en un navegador, generalmente se automatiza.
Se pueden pasar los datos originales enviados event.http.bodypero dado que es una codificación básica 64, primero debemos decodificarlo:
async function main(event) {
const formData = await convertMultipartFormDataToFormData(
Buffer.from(event?.http?.body ?? "", "base64").toString("utf8")
);
// ...
const body = !submissionValidationFailed.invalid_fields.length
? submissionSuccess
: submissionValidationFailed;
return { body };
}
Eso es todo. Con este enfoque, el resto es reemplazar la llamada a la API original con una llamada burlona.
Pensamiento final
En última instancia, ambos métodos ayudan a liberar la demostración de dependencias de API de terceros. En términos de esfuerzo, al menos en este ejemplo en particular, parecen comparables.
Es difícil superar el hecho de que los métodos de simulación manual no tienen dependencias externas, incluso en cosas que controlamos hasta cierto punto, y todo está unido. A menudo, hay buenas razones para apoyar este enfoque para presentaciones pequeñas e independientes sin conocer los detalles.
Pero el uso de una API de servidor simulada también tiene sus ventajas. La API del servidor simulada no solo impulsa las demostraciones, sino que también impulsa varios tipos de pruebas. Para necesidades más complejas, los equipos dedicados que trabajan en servidores simulados pueden preferir usar diferentes lenguajes de programación que JavaScript, o pueden optar por usar herramientas similares Ojo En lugar de comenzar desde cero.
Como con todo, depende. Además de lo que acabo de mencionar, hay muchos estándares a considerar.
También creo que este enfoque no necesariamente requiere la aplicación por defecto. Después de todo, mi demostración de CodePen funcionó durante cuatro años sin ningún problema.
La parte importante es que hay una manera de saber cuándo se rompe la demostración (monitoreo) y cuándo hacerlo, y puede usar las herramientas adecuadas para manejar la situación.