IIC2513-2017-2 / template

0 stars 0 forks source link

Templating engine #7

Closed raulmt closed 7 years ago

raulmt commented 7 years ago

Como conversamos en #2 , agregué koa-ejs. Transformé el par de acciones que tenemos a que usen templates EJS y dejé un layout mínimo default también.

raulmt commented 7 years ago

Ah… y agregué nvmrc con 8.4… así uno puede ejecutar nvm use y te setea la versión correcta (o te avisa que no la tienes instalada)

negebauer commented 7 years ago

Agregue el view que faltaba Me parece bien, listo para merge :+1:

wachunei commented 7 years ago

Otra cosa que surgió ahora que veo esto:

En el ejemplo de la ruta nameUrl se ofrece esa función como helper, muy parecido a los routing helpers de Rails. A medida que la aplicación crece y se van rendereando vistas con includes, estos helpers pueden ir mezclándose entre vistas, por ejemplo un routeo a los usuarios desde una vista de otro modelo, etc. En rails los métodos eran "globales", acá hay que pasárselo al la vista como "contexto" en la función render: ¿qué opinan de cómo organizarlos?

Yo haría dentro de los controladores (supongamos que existen) un folder helpers con los helpers varios, y los requeriría y asignaría en el controlador de la ruta, pero como no tenemos controladores y serán funciones inline, tendrían que estar en el mismo folder de las rutas.

Mi punto es que: por lo anterior, cada vez más me tinca separar a mano lo controladores en otro lugar, y solamente tener líneas en las rutas con: método, path, y controlador#función; y dentro de controlador#función hacer el manejo de las vistas, helpers, queries de modelos, etc.

¿qué opinan?

raulmt commented 7 years ago

@wachunei pero te estás refiriendo únicamente a que la misma función que al router le pasamos como arrow fn (router.get('name', '/path', ctx => something) la dejarías en un archivo aparte, dentro de folder controllers, en que sólo se exportan las funciones directamente? o sea:

# routes/hello.js
import { index } from '../controllers/hello';
...
router.get('hello', '/', index);

# controllers/hello.js
import { nameUrl } from '../helpers/hello.js';

export function index(ctx) {
  ctx.render('hello/index', { nameUrl })
}

Algo así? Igual podría ser en verdad… creo que no añade mucha carga cognitiva, e igual les permitiría dejas las cosas más ordenadas… pues, siendo honestos, seguro que tendrán algunas funciones de route handling medias grandes 😛

wachunei commented 7 years ago

Así mismo, a mi me hace sentido para hacer más concreto el patrón MVC.

On Aug 16, 2017, 9:35 PM -0300, Raúl Montes notifications@github.com, wrote:

@wachunei pero te estás refiriendo únicamente a que la misma función que al router le pasamos como arrow fn (router.get('name', '/path', ctx => something) la dejarías en un archivo aparte, dentro de folder controllers, en que sólo se exportan las funciones directamente? o sea:

routes/hello.js

import { index } from '../controllers/hello'; ... router.get('hello', '/', index);

controllers/hello.js

import { nameUrl } from '../helpers/hello.js';

export function index(ctx) { ctx.render('hello/index', { nameUrl }) } Algo así? Igual podría ser en verdad… creo que no añade mucha carga cognitiva, e igual les permitiría dejas las cosas más ordenadas… pues, siendo honestos, seguro que tendrán algunas funciones de route handling medias grandes 😛 — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

negebauer commented 7 years ago

A mi no me gusta la idea. Separar la ruta y controlador no agrega mucho, sobre todo teniendo que en routes se crea un archivo para cada ruta. Básicamente el routes/algo.js es a la vez la ruta algo y el controlador de algo En koa no me hace sentido separarlos E igual se pueden tener helpers

raulmt commented 7 years ago

@negebauer un archivo para cada ruta? es más bien un archivo por recurso, pues dentro tendrás varias rutas, para las CRUD+list+custom actions.

Creo que no es una pregunta respecto a koa, pues se aplica igualmente a express y cualquier otro framework que te permita asociar method+path a una función. La pregunta es, en esos casos, te conviene tener la función inline en el mismo archivo en donde especificas method+path, o te conviene declarar la función en otra parte y sólo dejar method+path=>referencia a fn en ese archivo?

Para archivos de router que sean pequeños tanto en líneas como en cantidad de rutas declaradas creo que da un poco lo mismo. Pero si cualquiera de esos dos números empiezan a crecer, sí te puede convenir declarar las funciones en otra parte, para poder tener mayor facilidad de ver las rutas. Si tienes

router.get('users.index', '/', usersController.index);
router.get('users.show', '/:id', usersController.show);
router.post('users.create', '/', usersController.create);
router.patch('users.update', '/:id', usersController.update);
…

puedes, tan fácilmente como lo hacías en Rails routes.rb, mirar las rutas que tienes… pero si tienes

router.get('users.index', '/', (ctx) => {
  // … 150 líneas
});

router.get('users.show', '/:id', (ctx) => {
  // … 150 líneas
});

Entonces ya no será tan fácil, te implicará hacer scroll por un archivo grande el tener una noción de los paths disponibles para el recurso users.

En el fondo, es la misma razón por la cual en algún momento una recomendación para JS que agarró vuelo era declarar las funciones al final del archivo, y usarlas al principio, aprovechando el hoisting. Así te queda un overview de la lógica más directamente disponible y sin tanta contaminación visual de montón de declaraciones, y si quieres "ver los detalles" bueno, vas a la declaración de la función en particular.

Lo que puse allá arriba, y a lo que se refería @wachunei , no es crear ninguna estructura especial… es seguir con el mismo enfoque de koa… sólo mover las funciones a otro archivo en lugar de dejarlas inline. Creo que la decisión de extraer declaración de funciones a otros archivos es más bien un tema de orden, archivos pequeños, facilidad para explorar, y no te cambian en nada la semántica de lo que estás haciendo. Quizá lo que te molesta es que esas declaraciones estén en una carpeta controllers, pensando en que ahí estamos como dándole semántica a esa separación?

negebauer commented 7 years ago

Si va por el tema de tener una carpeta de controllers. El mover las funciones si son my grandes me parece bien. Se puede hacer con sub routers Por ejemplo en vez de un src/routes/users.js que sea

router.get('users.index', '/', (ctx) => {
  // … 150 líneas
});

router.get('users.show', '/:id', (ctx) => {
  // … 150 líneas
});

Se pueden crear las sub rutas src/routes/users/index, src/routes/users/show, ... Donde cada sub ruta se encarga de un método particular y que otra los una

rodolfopalma commented 7 years ago

@negebauer usar subrouters de la forma que dices tendría como consecuencia anidar más la lógica de la aplicación. Creo que es mejor, considerando que no queremos anidar tantas carpetas ni crear un nuevo archivo para cada método, hacer la separación ruta/controlador.

raulmt commented 7 years ago

Haré merge de esto pues en cualquier caso la discusión sobre los helpers y controllers creo que va más allá del scope de este PR ;)