guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lightweight web modules for Guile?


From: Amirouche Boubekki
Subject: Re: Lightweight web modules for Guile?
Date: Sun, 01 Jul 2018 13:15:13 +0200
User-agent: Roundcube Webmail/1.1.2

On 2018-06-29 03:29, Tonton wrote:
Hey, I'm wanting to write a web page using guile, I'll need a module that can
help me with the web part. I like haunt, but I'll need a few dynamic
elements[1]. So I've been looking at and trying artanis. It is potentially awesome and does a lot of things I'm not familiar with - and I have yet to
make it work. (I just sent a request for aid to the artanis list)

Are there other libraries or modules that eases web development? Anything
between artanis and "plain" guile?

The sad story is that there is no such thing as "plain" guile for doing
webdev. I think I have done a fair amount of work around webdev without
resorting to Artanis. The last of them is called 'presence'. It's wip stalled dynamic blog engine. It stalled because I have a bug in the frontend for which I use biwascheme. So, it's a REST API with, so called, Single Page Application
written fully in Scheme [0]

I forked that project and got rid of the parts that are still (!) controversial, that is my database with, so called, minikanren querying and the biwascheme part. And made a git repository called guile-web [1]. If you want, it's backend framework for webdev, let's call it that. In reality it's no more that thin helpers on top
of 'plain' guile, an opinionated choice.

So here is what it bundles:

- sha2 + hmac for cryptographically signing cookies, copied from scheme industria

- argon2 bindings a new breed of memory & cpu strong [2] for hashing passwords [3] I translated how Python Django use that very same library. AFAIK there is no
  argon2 package in guix, yet...

- The entry point of the server is web:main but the interesting stuff is in the handler [4]. Which is basically the equivalent of the router. It's simply takes guile REQUEST and a BODY. Yes it's plain Guile. And dispatch based
  on request method and request path like any good backend router
using ice-9 match. It doesn't support regex, but who cares?! It doesn't support reversing url through a string indirection because it's an antipattern. Let's argue about that last point: The arguments about named routes are:

a) It allows to rework the url path later _without changing the name route_. If the path change is very likely that the logic of the path changed, otherwise why would you change the path in the first place? A slim chance you made a mistake and the original design. That's why you should give a fair amount of thought when design the request path routes but not too much! What I mean by that is that path are at the end of the day a detail. Not much endusers take advantage of it. Let's now, imagine I made a mistake (unlikely!) but I want to rework my routes and will leave the name of the route unchanged EVEN IF the logic behind changed? That would mean leaving some debt behind in the code, but it's ok because it's just a string (or a symbol). Very poor pratice, when you rework/refactor a codebase you should leave it better the best you can, especially if it's easy to do! In this case, you have to retype all (yes all the path!) that changed in the codebase. Nobody said it is not
       boring dull code. That's coding is, some fun, some boring stuff.

    b) It makes possible to reverse urls with a simple

(router-reverse 'name-of-the-route path-parameter-one path-parameter-two)

This. is. boilerplate. code. Very useless abstraction. Because the alternative is much simpler and lower the call stack depth and "complexity", which will ease reading the code. Behold the alternative to the above snipped:

(string-append "/name/of/the/route/" path-paramater-one "/" path-paramater-two)

Simple clean and newbie friendly. No need to abstract that path are made of
       strings with more strings!

   A Python dev, might tell you:

"I know better, I know object hierarchy <-> request path router. It's magiq!"

I am a Python. Gone there, Seen that. It's a pain. It's the of coding that some part of the code are dull and not 'funky' not algorithm heavy and dull easy.
  Rejoice about that, that's more time to think about interesting stuff!

- The router calls controllers with whatever they need as argument REQUEST or BODY depending on the case. In guile-web, I inlined that code in the
  handler aka. router:

    (render-html (template "index" "Héllo Guilers"))

Template is the base template procedure, that will return the sxml shell, and in this case will return the "index" as body class and "Héllo Guilers" as <body> content. render-html will translate that sxml to a plain guile response. SXML is awesome. Look at it closely. How much more complicated it can become than that! Look at Python mixt or JavaScript JSX or worse vuex if you want to have
  an idea of how simple things can be made complicated!

- There is also a helper for rendering static assets in development.

- There is a 'decode' procedure to translate query strings into association list https://github.com/a-guile-mind/guile-web/blob/master/src/web/decode.scm#L45

- There is a few helper for return 200, 303, 403, 404, 500, see:
https://github.com/a-guile-mind/guile-web/blob/master/src/web/helpers.scm

That's all!

What is missing is handling multipart mime type form encoded stuff. That means you can not handle form submission and uploads, yet. Patch very welcome. It worked around it in 'presence' because 'presence' sends scheme expression as request body.
I simply need to 'read/safe' that.

My opinion about Artanis is not very great because I don't find Django and Rails good for the long term. They deliver the wrong abstraction. ORM, regex routers, whatnot, global states, whatnot?!

[0] https://github.com/a-guile-mind/presence/blob/master/src/web.scm#L822
[1] git clone https://github.com/a-guile-mind/guile-web/
[2] It means it's very difficult to brute force the password even if
    one has both salt and pepper
[3] Mind this https://github.com/a-guile-mind/guile-web/issues/3
[4] https://github.com/a-guile-mind/guile-web/blob/master/src/web.scm#L53

Also there is guile-sqlite3 https://notabug.org/civodul/guile-sqlite3/

(Another possibility I entertained is to use haunt and have the dynamic
elements be a separate html page populated by a separate process on the
server. The page would then only be linked to from the rest of the pages and would hardcode paths for css and the rest. Not a very good solution, but
maybe the simplest right now.)


I would not do this, if I were you.

[1]: I need to embed messages from a pump.io account on the index page.
        I would also like to try integrating with one or two other web
        applications.

Tonton
        :-)


Happy hacking!

--
Amirouche ~ amz3 ~ http://www.hyperdev.fr



reply via email to

[Prev in Thread] Current Thread [Next in Thread]