Advanced Guides
Guía técnica: Migrar a Parse Server 3.1 en Back4App
25 min
más poder para tu aplicación con parse server 3 1 introducción la comunidad de parse lanzó recientemente la versión 3 1 de parse server https //docs parseplatform org/parse server/guide/ esta actualización ha limpiado la sintaxis del código en la nube es mucho más adecuada para aprovechar las construcciones async y await de es6 además, algunas idiosincrasias asociadas con el uso de parse fueron eliminadas, por ejemplo, las funciones en la nube simplemente devuelven una promesa en lugar de usar los error error o success success mensajes en el objeto de respuesta puedes actualizar tus aplicaciones en back4app fácilmente desde tu panel de control esta guía demostrará cómo actualizar tu código para aprovechar las nuevas características de 3 1 para seguir esta guía, te invitamos a echar un vistazo al proyecto de ejemplo proporcionado este es un tutorial de invitado escrito por john considine https //github com/considine , desarrollador principal en k optional https //koptional com/ objetivos actualizar tu parse server de back4app a 3 1 y migrar tu código en la nube en consecuencia requisitos previos para completar este tutorial, necesitas ° una aplicación existente de back4app que esté utilizando parse server 2 x ° sigue el tutorial de crear nueva aplicación para aprender cómo crear una aplicación en back4app resumen de cambios los cambios más notables son los siguientes 1\ cloud code se ejecuta con parse sdk 2 x anteriormente, cloud code se ejecutaba con parse sdk 1 x con parse server 3 1, se ejecuta parse sdk 2 x mira las versiones de parse sdk para entender mejor lo que esto implica este gran aumento de versión implica principalmente correcciones de errores también agrega containedby y includeall métodos de consulta, así como la capacidad de obtener un objeto con includes 2 actualización agregada desde parse 2 7 1, puedes usar el método aggregate en una consulta esto te permite aprovechar un poco más la base de datos subyacente ahora, la sintaxis para el método aggregate en parse query parse query ha sido actualizada puedes ejecutar una consulta utilizando dos etapas la match match y la group group etapa anteriormente, no necesitabas la clave pipeline en el objeto pipeline debido a la api subyacente, ahora debes incluir explícitamente la clave pipeline el valor debe ser un array de una o dos etapas, que presenta group group y match match mira documentación oficial de parse para más ejemplos específicos 3 optimizaciones internas se han realizado algunas optimizaciones internas por ejemplo, un parse livequery obtendrá los permisos de nivel de clase (clps) junto con los datos para evitar el acceso doble a la base de datos 4\ correo electrónico de restablecimiento de parse al solicitar un correo electrónico para restablecer la contraseña, el servidor devolverá éxito incluso si ese correo electrónico no está guardado además, los tokens de restablecimiento de contraseña expiran cuando se restablece el correo electrónico de un usuario 5\ actualización de disparadores en la nube con esta versión, puedes compartir datos entre el beforesave y aftersave disparadores en el mismo objeto por ejemplo 1 parse cloud beforesave('comment', async request => { 2 request context = { 3 foo 'bar' 4 }; 5 }); 6 7 parse cloud aftersave('comment', async request => { 8 console log(request context foo); //bar 9 }); puedes ver más sobre los cambios en parse server en el changelog oficial de parse 3 1 haciendo clic aquí 6\ mejora de livequery el cliente parse livequery te permite suscribirte a consultas y recibir actualizaciones del servidor a medida que llegan las consultas tradicionales se ejecutan una vez por el cliente, por lo que esto es muy útil para casos como mensajería, etc con back4app también puedes aprovechar esta tecnología https //www back4app com/docs/platform/parse server live query example con el lanzamiento de 3 x, la comunidad de parse ha mejorado el sistema para livequery acls https //docs parseplatform org/js/guide/#security for other objects ahora puedes pasar un token de sesión al método subscribe de una consulta en vivo, y el servidor parse solo devolverá resultados a los que este usuario tenga acceso por ejemplo, un usuario puede tener acceso de lectura/escritura a ciertos ‘mensajes’, pero no a todos 1 let query = new parse query('message'); 2 // you can get session token with 3 // parse user current() getsessiontoken() when logged in 4 let subscription = client subscribe(query, sessiontoken); el código anterior se suscribirá automáticamente a todos los mensajes a los que el usuario tenga acceso, liberándote de la responsabilidad de consultar mensajes específicos la parte principal de los cambios se refiere a cómo se maneja el código en la nube para esto, consulta la guía de migración a continuación 1 alineando fundamentos técnicos comenzaremos con un ejemplo de proyecto en la nube utilizando la versión 2 x de esa manera, podemos navegar a través de los cambios de sintaxis apropiados puedes ver el repositorio para este proyecto de ejemplo si estás familiarizado con async y await, puedes saltarte esta sección la evolución del código asíncrono en javascript se ve algo así funciones de callback promesas async / await cualquier aplicación moderna de javascript probablemente utilizará las tres las funciones de callback implican pasar una función como argumento a otra función esta segunda función puede ejecutar la primera en algún momento 1 // callbacks 2 // executes callback function after waiting 100 milliseconds 3 settimeout(function() { 4 alert('my callback function'); 5 }, 100); los callbacks son esenciales, pero pueden ser engorrosos cuando se trata de encadenar muchos de ellos específicamente, anidar varias capas puede ser difícil de leer, y el manejo de errores resulta complicado por lo tanto, en es2015 se introdujo la promesa 1 // promises 2 // executes several promises in a row with no significant nesting 3 const mypromise = new promise(function(resolve, reject) { 4 settimeout(function() { 5 if (math random() < 0 2) reject(new error('random failure!')); 6 resolve('finished'); 7 }, 100); 8 }); 9 10 // executes this promise 4 times and catches errors involved 11 mypromise 12 then(() => mypromise) 13 then(() => mypromise) 14 then(() => mypromise) 15 then(() => mypromise) 16 catch(e => console log(e)); las promesas mejoran la legibilidad de la programación asíncrona también hacen que los pipelines sean más explícitos pero se lograron avances aún mayores en es2017 con las construcciones async / await tu código ahora puede esperar los resultados de una promesa sin depender de los bloques then / catch (que también pueden volverse difíciles de leer) 1 // using the definition of mypromise from the above code 2 async function foo() { 3 try { 4 let result = await mypromise; 5 result = await mypromise; 6 result = await mypromise; 7 } catch (e) { 8 console log(e); 9 } 10 } quizás para un ejemplo muy simple, esto puede no parecer más elegante que las promesas simples pero esperar los resultados de una función asíncrona es a menudo precisamente lo que queremos hacer por lo tanto, realmente optimiza la legibilidad de nuestro código soporte para async/await como se mencionó anteriormente, async/await se incluyó en la especificación de ecmascript 2017 (es8) para el código del servidor, la versionado no es un problema ya que puedes actualizar a la versión de node js que soporta estas características ten la seguridad de que el entorno de back4app soporta versiones estables recientes para el código del navegador, transpiladores como babel producirán un es2016 compatible con código que utiliza async / await y funciona en navegadores modernos 2 pensando en tu código de manera diferente el cambio principal con cloud code implica lo que hace el desarrollador frente a lo que hace la biblioteca anteriormente, gestionarías explícitamente la respuesta dado que la mayoría del cloud code se ejecutará de manera asíncrona realizando consultas y escrituras en la base de datos tiene más sentido devolver una promesa, reduciendo el código repetitivo la intuición detrás de las funciones en la nube es que hay una configuración y configuración mínima involucrada al escribir código del lado del servidor esta versión encarna esa idea; ten esto en cuenta mientras refactorizas y creas nuevas funciones para mostrar cómo funcionan las funciones de cloud code en parse server 3 1, reescribimos un ejemplo funcional de cloud code de una versión de parse server antes de la migración puedes encontrar este código haciendo clic aquí la misma función de cloud code está escrita en parse 3 1 como se muestra a continuación 1 // cloud code before migration 2 // full code found in link above 3 const post = 'post'; 4 parse cloud define('posts\ get', function(request, response) { 5 // needs a post id 6 return new parse query(post) 7 get(request params id, { usemasterkey true }) 8 then(post => { 9 response success(post); 10 }) 11 catch(e => { 12 response error({ message e message }); 13 }); 14 }); 3 agregando todos los marcadores async cualquier función que use await debe ser declarada con el modificador async esta simple refactorización adjuntará async a todas las cloud functions también las reemplazará con funciones flecha ya que son más concisas en este caso (y lo que utiliza la guía oficial de parse actualizada) 1 // snippet of step 2 code refactoring see full code 2 // here in the link at the top of this step 3 const post = 'post'; 4 const comment = 'comment'; 5 6 parse cloud define('posts\ get', async (request) => { 7 // needs a post id 8 return new parse query(post) 9 get(request params id, { usemasterkey true }); 10 } tu código se verá como esto después de esta refactorización nada loco hasta ahora en el siguiente paso, obtendremos el valor de nuestro dinero por este cambio 4 eliminando referencias a la respuesta, emplear await tu código se verá como esto después de esta refactorización este paso es un poco más complicado necesitamos eliminar todas las referencias a la variable ‘response’, devolviendo una promesa en su lugar en el caso de múltiples funciones de consulta/guardado, espera la respuesta consulta el método de creación de comentarios para ver cómo se hace 1 // snippet of step 3 code refactoring see full code 2 // here in the link at the top of this step 3 parse cloud define('comment\ create', async request => { 4 // post should have text and should have a user and a post id 5 if (!request user) { 6 throw new error('unauthenticated!'); 7 } 8 9 if (!request params text) { 10 throw new error('a comment needs text!'); 11 } 12 if (!request params post id) { 13 throw new error('a comment needs a post!'); 14 } 15 16 // get the post 17 18 const post = await new parse query(post) get(request params post id, { 19 usemasterkey true 20 }); 21 return new parse object(comment, { 22 text request params text, 23 user request user, 24 post post 25 }) save(null, { usemasterkey true }); 26 }); ten en cuenta que ahora se lanza un error de javascript en lugar de llamar a response error parse se encargará de transformar esto en una respuesta para nosotros eliminar un ‘post’ o ‘comentario’ implica primero obtener el objeto, y luego destruirlo al usar ‘await’, el método de destrucción puede acceder al objeto guardado fuera de un bloque eso completa toda la refactorización necesaria para la migración es decir, si llegas hasta este paso, ¡felicitaciones! ¡tu código funcionará en back4app parse 3 1! 5 trucos avanzados (opcional) los siguientes cambios son opcionales, pero pueden acortar significativamente tu código encuentro que reducen el código repetitivo probablemente notaste muchos chequeos manuales para parámetros o el usuario autenticado estos aseguran que no ocurra un comportamiento extraño por ejemplo, hemos decidido que nuestro objeto ‘post’ necesita texto, así que si no se pasa un parámetro ‘text’, el objeto se guardará sin él una forma de prevenir esto es verificar que se haya pasado texto pero los chequeos manuales pueden ser que consuman tiempo y sean inelegantes en esta sección, aprovechamos la desestructuración de objetos para completar implícitamente estas verificaciones deberías ver la documentación anterior si no sabes qué es la desestructuración pero en resumen, te permite convertir la propiedad de un objeto en una variable con una sintaxis muy concisa 1 // this 2 var obj = { 3 hi true, 4 bye false 5 }; 6 var hi = obj hi; 7 var bye = obj bye; 8 9 // is equivalent to this 10 var obj = { 11 hi true, 12 bye false 13 }; 14 var { hi, bye } = obj; 15 16 console log(hi); 17 // true 18 console log(bye); 19 // false la desestructuración es menos verbosa que la asignación manual también te permite declarar variables de parámetros sobre la marcha, lo cual es agradable 1 parse cloud define('posts\ get', async ({ params { id } }) => { 2 // id is declared 3 }); cuando se combina con una notación de es2015 para inicialización de objetos podemos optimizar nuestras verificaciones de parámetros podemos hacer esto 1 // iterates through object's keys makes sure, for each key, the value is set 2 const assertparams = parameter obj => { 3 for (var key of object keys(parameter obj)) { 4 if (typeof parameter obj\[key] === 'undefined') 5 throw new error(`missing parameter ${key}`); 6 } 7 }; 8 9 var obj = { 10 hi true, 11 bye false 12 }; 13 var { hi, undef, bye } = obj; // undef will be undefined 14 var check 1 = { hi, bye }; 15 var check 2 = { hi, undef }; 16 17 // check = { hi true, no undefined } 18 assertparams(check 1); // passes 19 assertparams(check 2); // throws error así que para nuestro código de parse, podemos hacer esto 1 // snippet of advanced code refactoring see full code 2 // here in the link at the top of this step 3 parse cloud define('posts\ delete', async ({ user, params { id } }) => { 4 // makes sure user is authenticated, and id parameter is passed 5 assertparams({ user, id }); 6 const post = await new parse query(post) get(id, { 7 usemasterkey true 8 }); 9 return post destroy({ usemasterkey true }); 10 }); si esto es desalentador, no te preocupes el código completo el ejemplo podría ayudar en resumen, ‘assertparams’ es una función de utilidad para lanzar un error si un valor es indefinido podemos verificar los parámetros en un solo movimiento combinando la desestructuración de objetos y la inicialización de objetos de es2015 esto elimina ocho o nueve verificaciones manuales que comienzan a volverse antiestéticas después de un tiempo 6 actualizando en back4app una vez que hayas migrado tu código, debes hacer dos cosas más para que funcione en back4app actualiza la versión de tu servidor back4app sube tu nuevo código en la nube he mencionado brevemente el primer paso antes todo lo que necesitas hacer es iniciar sesión en back4app y ir al panel de control de tu aplicación desde allí, solo selecciona “configuración del servidor” a la izquierda, seguido del botón “configuraciones” en la tarjeta “administrar parse server” luego puedes seleccionar el botón de opción del parse server 3 1 1 y hacer clic en “guardar” por último, pero no menos importante, puedes subir tu código a través del back4app cli https //blog back4app com/2017/01/20/cli parse server/ , o desde tu panel de control utilizando la carga manual consulta esta guía https //www back4app com/docs/android/parse cloud code si necesitas más información sobre este paso notas sobre el lanzamiento de una nueva versión si tu código es complejo, podría ser una buena idea realizar algunas pruebas antes de hacer estos dos pasos back4app tiene algunas guías sobre cómo hacer esto aquí y aquí finalmente, es importante notar que estos cambios son breaking usar el código que escribimos en un servidor parse 2 x fallará, y usar código 2 x en un servidor 3 1 también fallará por lo tanto, debes asegurarte de actualizar tu versión de back4app justo cuando subas tu cloud code actualizado si tienes muchos usuarios y te preocupa que la carga del código y la actualización de la versión estén ligeramente desincronizadas, puedes hacer algo como esto 1 const serverversion = 2 parse coremanager get('version') === 'js1 11 1' ? 'old' 'new'; 3 4 if (serverversion === 'new') { 5 parse cloud define('posts\ get', async ({ params { id } }) => { 6 assertparams({ id }); 7 // needs a post id 8 return new parse query(post) get(id, { 9 usemasterkey true 10 }); 11 }); 12 } else if (serverversion === 'old') { 13 // old definition here 14 } este código determina dinámicamente la versión y define las funciones en la nube en función de eso después de subir esto, cambiarías a 3 1, y luego podrías volver a subir el código con la parte antigua eliminada incluir la verificación al principio asegura que no haya un punto en el que tu código se bloquee dado que puedes actualizar y subir en un par de segundos, generalmente no es necesario conclusión en esta guía, demostramos simplemente cómo migrar tu cloud code a la versión 3 1 de parse recuerda actualizar tu versión de back4app a 3 1 después de hacer estos cambios también es importante, esta guía demostró una sintaxis mejorada que parse 3 1 aprovecha nuestras refactorizaciones redujeron la base de código de 160 líneas a 90 y la hicieron mucho más legible para aplicaciones reales, esto dará dividendos