Discussion:
Lightweight web modules for Guile?
Tonton
2018-06-29 01:29:44 UTC
Permalink
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?


(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.)


[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
:-)
--
I use gpg to sign my emails. All the symbols you may see at the bottom
of this mail is my cryptographic signature. It can be ignored, or used
to check that it really is me sending this email. Learn more by asking
me or see: https://u.fsf.org/zb or https://ssd.eff.org/
tantalum
2018-06-29 18:42:15 UTC
Permalink
hi, not sure if it is exactly what your looking for but it might be
useful for examples and matches the general question.
i maintain a project named "web-app" at http://sph.mn/c/view/mu or
https://github.com/sph-mn/sph-web-app
the core is small and working well for me so far, ive been maintaining
it for a long time. it starts a server and for each request gives a
request object to a user defined procedure, which then returns a
response object that is send back to the client.
it comes with an optional module for file processing (templates,
preprocessed files, bundling, etc) and has some more cool features like
protocol independence (socket -> app -> socket), an exchangeable server
(fibers included) and derived projects (using modules and symlinks).

the project hasnt gone through testing and feedback loops with other
users, and the documentation, while technically probably up to date,
needs revision i think. here is a minimal usage example, in a file named
"example.scm":

(import (sph web app) (sph web app http))
(define (app-respond request) (respond "test"))
(define app (swa-create (quote project-name) app-respond))
(swa-start app #f swa-server-guile)

then running "guile example.scm" displays

listening on 127.0.0.1:6500
exit with ctrl+c

the app is then accessible with the browser at http://127.0.0.1:6500
Tonton
2018-06-29 21:21:55 UTC
Permalink
Hey.

Thank you both tantalum and Zelphir!

I'm not entirely sure what I need myself to be honest, this is very much a
learning exercise; even though I have a goal to use it. That said, the
web-app project looks more like what I'd like. I'll probably package it for
guix also, if I use it.

On Fri, 29 Jun 2018 18:42:15 +0000
Post by tantalum
hi, not sure if it is exactly what your looking for but it might be
useful for examples and matches the general question.
i maintain a project named "web-app" at http://sph.mn/c/view/mu or
https://github.com/sph-mn/sph-web-app
the core is small and working well for me so far, ive been maintaining
it for a long time. it starts a server and for each request gives a
request object to a user defined procedure, which then returns a
response object that is send back to the client.
it comes with an optional module for file processing (templates,
preprocessed files, bundling, etc) and has some more cool features like
protocol independence (socket -> app -> socket), an exchangeable server
(fibers included) and derived projects (using modules and symlinks).
the project hasnt gone through testing and feedback loops with other
users, and the documentation, while technically probably up to date,
needs revision i think. here is a minimal usage example, in a file named
(import (sph web app) (sph web app http))
(define (app-respond request) (respond "test"))
(define app (swa-create (quote project-name) app-respond))
(swa-start app #f swa-server-guile)
then running "guile example.scm" displays
listening on 127.0.0.1:6500
exit with ctrl+c
the app is then accessible with the browser at http://127.0.0.1:6500
Amirouche Boubekki
2018-06-30 17:15:32 UTC
Permalink
Hey.pp project looks more like what I'd like. I'll probably packa
Thank you both tantalum and Zelphir!
I'm not entirely sure what I need myself to be honest, this is very much a
learning exercise; even though I have a goal to use it. That said, the
web-app project looks more like what I'd like. I'll probably package it for
guix also, if I use it.
Let me know how it works
On Fri, 29 Jun 2018 18:42:15 +0000
Post by tantalum
hi, not sure if it is exactly what your looking for but it might be
useful for examples and matches the general question.
i maintain a project named "web-app" at http://sph.mn/c/view/mu or
https://github.com/sph-mn/sph-web-app
the core is small and working well for me so far, ive been maintaining
it for a long time. it starts a server and for each request gives a
request object to a user defined procedure, which then returns a
response object that is send back to the client.
it comes with an optional module for file processing (templates,
preprocessed files, bundling, etc) and has some more cool features like
protocol independence (socket -> app -> socket), an exchangeable server
(fibers included) and derived projects (using modules and symlinks).
the project hasnt gone through testing and feedback loops with other
users, and the documentation, while technically probably up to date,
needs revision i think. here is a minimal usage example, in a file named
(import (sph web app) (sph web app http))
(define (app-respond request) (respond "test"))
(define app (swa-create (quote project-name) app-respond))
(swa-start app #f swa-server-guile)
then running "guile example.scm" displays
listening on 127.0.0.1:6500
exit with ctrl+c
the app is then accessible with the browser at http://127.0.0.1:6500
--
Amirouche ~ amz3 ~ http://www.hyperdev.fr
Amirouche Boubekki
2018-07-01 11:15:13 UTC
Permalink
This post might be inappropriate. Click to display it.
Arne Babenhauserheide
2018-07-01 22:21:24 UTC
Permalink
This post might be inappropriate. Click to display it.
Tonton
2018-07-15 00:06:52 UTC
Permalink
Hey!

Sorry about the long response time, lost myself for a while. :-)

Thanks a lot for the thorough walkthrough Amirouche!

I've not had time to continue the web project recently, but look very much
forward to continue exploring both artanis and the web-projects/helpers
mentioned in these threads. Especially the web-app project of tantalum.

Again, thanks.
:-)

On Sun, 01 Jul 2018 13:15:13 +0200
Post by Amirouche Boubekki
Post by Tonton
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.
- 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
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
(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!
"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
(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
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/
Post by Tonton
(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.
Post by Tonton
[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!
--
I use gpg to sign my emails. All the symbols you may see at the bottom
of this mail is my cryptographic signature. It can be ignored, or used
to check that it really is me sending this email. Learn more by asking
me or see: https://u.fsf.org/zb or https://ssd.eff.org/
Loading...