shipharbor / merry

:ocean::ocean::sailboat::ocean::ocean: - cute streaming API framework
MIT License
312 stars 21 forks source link

Recommended approach to templates, HTML or other #54

Closed callum closed 7 years ago

callum commented 7 years ago

I really like the stream-based request handling you've got going on. I wondered if you knew of any cool approaches to templating that fit this model nicely.

There are lots of go-to solutions to templates in Node, some of which are quite bloated in my opinion. I'm curious to know what fits with the pared-down nature of merry, streaming or otherwise.

Really awesome work on merry so far, thanks! The error handling and logging is really great.

yoshuawuyts commented 7 years ago

I've been experimenting a little bit in this regard, but don't have a neat solution quite yet. I'd probably build something to .toString() a choo application and then run it through a combination of:

Hope this helps, cheers! :v:

callum commented 7 years ago

Cool, thanks. I've come across hyperstream before, and whilst the idea is cool, it's just not as simple as plain old string-based templates. I guess that's just the nature of sync vs async. And 'streaming at a CSS selector' feels kind of odd too; having to write your HTML in such a way that data can be inserted into it later on. Anyway, opinions...

This is kind of related: From what I can tell from the source merry is designed around the creation of JSON APIs - is that right? Currently if I send an error in my app it spits out JSON. I wondered how you might prettify these somehow in a HTML app, i.e. web browsers requesting text/html. Kind of like how you're prettifying the app logs I guess. Seems like error handling is currently hardwired to send JSON, so I'm interested to hear how you might handle that.

Hope you don't mind all the questions. This is a really interesting project - I'm loving reading through the source and checking out the deps to see what's gone into it.

callum commented 7 years ago

An idea: https://github.com/hapijs/accept

Then check the request headers when handling an error to see whether to respond with HTML or JSON.

callum commented 7 years ago

This is a really cool idea for templates that I think you would dig: https://github.com/almost/stream-template

tunnckoCore commented 7 years ago

@callum Why not just use from2-string to convert your html templates into streams? :) stream-template seems a bit interesting but it isn't big deal.

callum commented 7 years ago

@tunnckoCore surely that's less efficient if you're serving lots of requests? It doesn't really matter that much for my app, but I'm interested to know the trade-offs if there are any.

yoshuawuyts commented 7 years ago

From2-string is not a half bad idea; I'd use it. That said, you probably want to cache static templates at the nginx level; letting Node handle it is not ideal per se. On the other hand: there's also something like prematurely optimizing

On Sun, Jan 22, 2017, 11:25 callum notifications@github.com wrote:

@tunnckoCore https://github.com/tunnckoCore surely that's less efficient if you're serving lots of requests? It doesn't really matter that much for my app, but I'm interested to know the trade-offs if there are any.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/yoshuawuyts/merry/issues/54#issuecomment-274322295, or mute the thread https://github.com/notifications/unsubscribe-auth/ACWleh3ONQM8-1fln4_w0lZFBPTxvihCks5rUy57gaJpZM4Lk_nm .

callum commented 7 years ago

This is what I have working at the moment. My main concern around templates is that when I'm pulling stuff out of the db I don't want to be buffering all the rows into an array for every request. Is this a good approach, or just overkill?

var map = require('through2-map')
var pump = require('pump')
var pumpify = require('pumpify')
var tmpl = require('html-template')

var holiday = require('./lib/models/holiday')
var template = require('./lib/template')

module.exports = index

function index (ctx, done) {
  var html = tmpl()
  var page = pumpify(template('holidays/index.html'), html)

  done(null, page)

  pump(
    holiday.list(),
    map.obj(function (row) {
      return {
        '[key=name]': row.user.name,
        '[key=status]': row.status,
        '[key=start]': new Date(row.start).toDateString(),
        '[key=end]': new Date(row.start).toDateString()
      }
    }),
    html.template('holiday', { include: false }),
    function (err) {
      if (err) return done(err)
    }
  )
}
yoshuawuyts commented 7 years ago

I'd cache what is cacheable, for example cache static html into a buffer and then repeatedly create a stream from it. Using a regular string isn't ideal because I bet under the hood it isn't a flat string which means it'll take longer to push out. I think casting to a buffer that's then repeatedly streamed is the most efficient way to approach this. Then with hyperstream inject what you need to inject from your database stuff. This is never going to scale brilliantly, but it's the best we can do in Node I reckon.

On Sun, Jan 22, 2017 at 12:55 PM callum notifications@github.com wrote:

This is what I have working at the moment. My main concern around templates is that when I'm pulling stuff out of the db I don't want to be buffering all the rows into an array for every request. Is this a good approach, or just overkill?

var map = require('through2-map')var pump = require('pump')var pumpify = require('pumpify')var tmpl = require('html-template') var holiday = require('./lib/models/holiday')var template = require('./lib/template') module.exports = index function index (ctx, done) { var html = tmpl() var page = pumpify(template('holidays/index.html'), html)

done(null, page)

pump( holiday.list(), map.obj(function (row) { return { '[key=name]': row.user.name, '[key=status]': row.status, '[key=start]': new Date(row.start).toDateString(), '[key=end]': new Date(row.start).toDateString() } }), html.template('holiday', { include: false }), function (err) { if (err) return done(err) } ) }

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/yoshuawuyts/merry/issues/54#issuecomment-274326452, or mute the thread https://github.com/notifications/unsubscribe-auth/ACWlevAb5XictwgW7IJzEEkyiZIfV5GGks5rU0OZgaJpZM4Lk_nm .

callum commented 7 years ago

Thanks - really appreciate the advice

tunnckoCore commented 7 years ago

surely that's less efficient if you're serving lots of requests?

@callum I know that, but there not so many streaming template engines/langs. So the truth is somewhere here - converting string to streams ;d

yoshuawuyts commented 7 years ago

cool, think this is resolved nowwww :sparkles: :sparkles: :sparkles: :sparkles: :sparkles: