# Realworld Api Backend with concurrent-task

**URL:** <https://discourse.elm-lang.org/t/realworld-api-backend-with-concurrent-task/9596>\
**Category:** Show and Tell\
**Created:** [January 18, 2024, 9:02am UTC](https://discourse.elm-lang.org/t/realworld-api-backend-with-concurrent-task/9596 "2024-01-18T09:02:14Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![andrewMacmurray](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/andrewmacmurray/32/2797_2.png) [@andrewMacmurray](https://discourse.elm-lang.org/u/andrewMacmurray)\
**Post date:** [January 18, 2024, 9:02am UTC](https://discourse.elm-lang.org/t/realworld-api-backend-with-concurrent-task/9596/1 "2024-01-18T09:02:14Z")

</div>

Hello friends,

I’ve been playing around with [elm-concurrent-task](https://package.elm-lang.org/packages/andrewMacmurray/elm-concurrent-task/latest/) and what a backend http setup could look like with it. I ended up implementing the realworld backend api spec with it; I had a lot of fun in the process!

(Please correct me if I’m wrong) I think this is the first backend spec compliant Elm implementation.

## Links

- You can see a [full stack Elm version of conduit](https://realworld-backend-elm.vercel.app/) (it’s this backend api connected up to the original [elm-spa-example](https://github.com/rtfeldman/elm-spa-example/tree/master)).
- Check out [the repo here](https://github.com/andrewMacmurray/realworld-backend-elm).

## How it works

- The api is an Elm worker running on NodeJS, and uses [elm-concurrent-task](https://package.elm-lang.org/packages/andrewMacmurray/elm-concurrent-task/latest/) to interop with a few JS libraries and a Postgres database.
- All of the business logic can be found in [Routes.elm](https://github.com/andrewMacmurray/realworld-backend-elm/blob/main/src/elm/Routes.elm) and in [Domain](https://github.com/andrewMacmurray/realworld-backend-elm/tree/main/src/elm/Domain) modules.
- Each endpoint handler is a `ConcurrentTask` which handles a thin layer of interop with some JS libraries (`bcryptjs`, `jsonwebtoken` and `node-pg`).
- All of the code in Lib is pretty generic and could more or less be extracted out into separate packages as is (For [JWT](https://github.com/andrewMacmurray/realworld-backend-elm/blob/main/src/elm/Lib/Crypto/Jwt.elm), [Bcrypt](https://github.com/andrewMacmurray/realworld-backend-elm/blob/main/src/elm/Lib/Crypto/BCrypt.elm), [Postgres](https://github.com/andrewMacmurray/realworld-backend-elm/blob/main/src/elm/Lib/Database/Postgres.elm) and an [Http Server](https://github.com/andrewMacmurray/realworld-backend-elm/blob/main/src/elm/Lib/Http/Server.elm)).
- It’s deployed on a single vercel serverless function, with vercel postgres for storage.

I’m quite pleased with how clean it’s turned out (particularly the http layer). The database layer is pretty minimal and not very typesafe, but could definitely iterate on it.

Curious to hear any thoughts or suggestions.

---

<div class="post-metadata">

**Author:** ![ni-ko-o-kin](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ni-ko-o-kin/32/2693_2.png) [@ni-ko-o-kin](https://discourse.elm-lang.org/u/ni-ko-o-kin)\
**Post date:** [January 19, 2024, 8:17am UTC](https://discourse.elm-lang.org/t/realworld-api-backend-with-concurrent-task/9596/2 "2024-01-19T08:17:44Z")

</div>

This is replacing my [naive implementation](https://github.com/ni-ko-o-kin/elm-node) and extends it with so much more functionality, type safety and better code.

Are you using this architecture in production?

Am I reading the code correctly: you are starting up one elm worker and then accepting http requests concurrently? How do you not mix up requests and their corresponding responses?

An elm worker has a state (model), so it should be possible to implement a rate limiter inside elm, right?

Upon further reading the code, it seams that elm-concurrent-task is the piece that makes all this possible (as you stated in the first line 😉 ).

**Big thanks to you** for sharing this!

---

<div class="post-metadata">

**Author:** ![andrewMacmurray](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/andrewmacmurray/32/2797_2.png) [@andrewMacmurray](https://discourse.elm-lang.org/u/andrewMacmurray)\
**Post date:** [January 19, 2024, 8:55am UTC](https://discourse.elm-lang.org/t/realworld-api-backend-with-concurrent-task/9596/3 "2024-01-19T08:55:43Z")

</div>

Thanks! Glad it’s been useful.

I’m using something close to this in production, it’s low traffic but it behaves well!

Yep you’re right about the rate limiter, the server endpoints are all stateless but underneath there’s the stateful program:

> <https://github.com/andrewMacmurray/realworld-backend-elm/blob/main/src/elm/Lib/Http/Server.elm#L614-L702>

You could add logic + state for rate limiting at this level if you wanted.

Making sure requests + responses aren’t mixed up is a clever trick (credit to @eberfreitas) where you create a `new Promise` on request and pass the `resolve` function through Elm (as an `Json.Encode.value`). When the response is ready, JS calls the passed `resolve` function.

It’s pretty handy as it makes it very easy to use with any server framework.

Here’s the code:

> <https://github.com/andrewMacmurray/realworld-backend-elm/blob/main/src/api.ts#L47-L53>

Here’s the article:

> **[Elm in the server (or anywhere else) with promises](https://dev.to/eberfreitas/elm-in-the-server-or-anywhere-else-with-promises-5eoj)**
>
> Elm was created to run on the browser, but every once in a while someone will ask about how to run El...

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [January 29, 2024, 8:56am UTC](https://discourse.elm-lang.org/t/realworld-api-backend-with-concurrent-task/9596/4 "2024-01-29T08:56:00Z")

</div>

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