Aino, an experimental HTTP framework for Elixir

(blog.oestrich.org)

97 points | by clessg 941 days ago

5 comments

  • sergiomattei 941 days ago
    > I have listened to several mentors of mine from REST Fest talk about how we shouldn’t keep state on the server for web/API clients. It’s conversations and lessons like these that are guiding me towards exploring something like Aino.

    I feel the same way. I'm not a fan of approaches that keep so much state on the server (LiveView and its clones). That's a disagreement I have with Phoenix's general direction.

    • dnautics 941 days ago
      Out of curiosity what is the objection (and is it any worse than keeping a database on the server?)
      • zdragnar 940 days ago
        Imagine the database were compiled into the application itself. If you only ever have one http server and one database, it's not an issue. If you run into load issues and need to scale out, things become trickier. Moving the database to its own application (say, mongo or redis or postgres) means that your main application can now reside on one machine while your database(s) can reside on a beefier machine (or just multiple machines).

        Likewise, 'stateful' applications keep local state, and 'stateless' applications push everything off to either the client or database. They become fungible commodities- at peak load, you can quickly spin up more and shut them down after. With a 'stateful' application, you need to keep it running as long as the sessions (and maybe background jobs or any other local state) are live, unless you have some trivial means of passing that off to another machine.

        Load balancing also means needing sticky sessions (i.e. once a client connects to an application server behind the load balancer, the load balancer needs to be able to keep sending the client to the same server). It's a solved problem, but needing to deal with it at all is a thing.

        The web got along just fine with stateful applications for years, and things like websockets mandate a certain amount of statefulness, so there's nothing wrong with using it if you want to... OTOH you might just save yourself a lot of pain and effort if you don't. Right tools for the right jobs and all that.

        • dnautics 940 days ago
          Most of these things are pretty easy in elixir phoenix... And the tradeoff is that if you are sending gobs of http and also doing a fresh db query each time, it's wasteful and can possibly hurt latency too; phoenix tries to solve that. Conceptually one way you can think of it is that it's just a "smarter (in the feature sense, not necessarily the access-optimized sense) cache layer" in front of your DB.
    • te_chris 940 days ago
      In my practical experience of a moderate sized e-commerce site heavily using liveview I LOVE state on the server. Not having an API and heavy client code is so great.
  • rhizome31 940 days ago
    > With the current trajectory of Phoenix, I’ve been thinking a lot on how to keep “dead views” still alive. I personally think they have a seat at the table. I have listened to several mentors of mine from REST Fest talk about how we shouldn’t keep state on the server for web/API clients.

    I don't understand this part. What are "dead views"? I would have thought maybe they are views to which no client is connected anymore, but the rest of the paragraph seems to contradict that. What is the "current trajectory of Phoenix" that is alluded to?

    • dugmartin 940 days ago
      "Dead views" are what folks are now calling non-LiveView routes in a Phoenix app. I think it will sort itself out - LiveView has its place but non-LiveView routes have theirs too.
      • rhizome31 940 days ago
        Thank you, it makes sense now! I had missed that bit of lingo.
  • ch4s3 941 days ago
    Eric is a really sharp guy, I’m super interested to see where he goes with this. The ideas of a Clojure/Ring inspired HTTP framework in Elixir land it really cool.
  • travisgriggs 941 days ago
    Would this be better/simpler for API/endpoints?
    • peoplefromibiza 940 days ago
      I think for simple API endpoint Plug is still the best option

      A simple example

          defmodule AddressParser.PlugHandler do
            import Plug.Conn
            require Logger
      
            def init(options) do
              Logger.info("Running #{__MODULE__} with Plug using http://0.0.0.0:8080")
              options
            end
      
            def call(
                  %Plug.Conn{method: method, request_path: request_path, query_string: query_string} = conn,
                  _opts
                ) do
              request_id = generate_request_id()
              Logger.info("#{request_id} #{method} #{request_path} #{query_string}")
      
              case handle_request(method, request_path, URI.decode_query(query_string)) do
                {:ok, response} ->
                  Logger.info("#{request_id} sent 200 ok")
      
                  conn
                  |> put_resp_content_type("application/json")
                  |> send_resp(200, Jason.encode!(response))
      
                {:error, status, response} ->
                  Logger.error("#{request_id} sent #{status} #{response}")
      
                  conn
                  |> put_resp_content_type("text/html")
                  |> send_resp(status, response)
              end
            end
      
            defp handle_request("GET", "/parse", %{"address" => address}) do
              {:ok, Address.parse(address)}
            end
      
            # more handlers
            ...
          end
  • abrokenpipe 941 days ago
    Reminds me of sinatra