Writing simple servers in Elm

This little script runs an Elm program as a simple HTTP server.

I have some blog posts written for Acadia (about row-level security, symbolic evaluation, and optimistic locking) and they definitely benefit from being paired with full client/server/database examples.

Please share if you make something with this! I always do “beauty in the code, not the styling” to keep my examples minimal, but I would love to see some more complete applications!

32 Likes

This is very cool! I’d love to hear updates from anyone who uses this :slight_smile:

1 Like

I was doing something very similar during the early Acadia alpha and I very much liked it. The primary difference with my setup was that I had (generated) encoders/decoders for the endpoints do that instead of

case req.url of
  "/' ->
  "/profile" ->
  ...

I had

case decodeUrl req.url of
  Just Home ->
  Just Profile ->
  ...

This made it easy to not typo a URL, as well as make sure I handled them all. I also had a module for methods and for status codes. The status codes one I really like because I couldn’t tell you (without looking it up) what 307 means but I can explain the words TemporaryRedirect.

I do really like the req.__elm_body approach too. I hadn’t thought to do that and I think it makes some parts of the JS side easier.


For the encoding/decoding I forked elm-serialize 1.3.1 to add support for the expanded Acadia types (Int64, Int8, Float32, etc). Then I had a fairly rudimentary elm-pages script that parsed the generated Baclend.elm that comes from Acadia and generated the necessary encoders/decoders for types.

If you want to read the messy code GitHub - wolfadex/inventory-app · GitHub. Please note that I consider this to be pretty messy even for myself, but I figure I don’t need to keep it locked away forever. Parts of the Acadia code are decently outdated too.

6 Likes

I have a similar approach. The

type Request
    = Auth AuthRequest.Request
    | User UserRequest.Request
    | Invoice InvoiceRequest.Request
    -- ...

and

type Response
    = Error ErrorResponse.Error
    | Auth AuthResponse.Response
    | User UserResponse.Response
    | Invoice InvoiceRespones.Response
    -- ...

are both shared on the elm client and elm server. So only valid requests can be build on the client for the server and only valid responses on the server for the client. You still have to pattern match on the expected response on the client. I wanted to you have maximum type safety.

This has some trade offs too, like no route level rate limiting on the nginx side because all routes are handled through one POST route /api (the actual path is hidden in the json body of the request).

I’m looking forward to using Acadia for accessing the database to extend the type safety further! Exciting times ahead!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.