in web application development, the process of managing internal server endpoints feels like it ought to be automated
(and surely some frameworks do automate it!)
in the worst case scenario, nothing happens automatically. product wants a "launch nukes" button, so backend adds a /api/launch-nukes endpoint and frontend makes use of it. since data is being sent over the wire, it has to be serialized, meaning that both frontend and backend have to write serialization logic of some kind to translate between domain objects and what's being sent over the wire
we can make serialization automatic in at least two ways:
-
choose JSON for our serialization language, then on both frontend and backend use a language like Javascript or Python which have ergonomic built-in data structures that translate roughly one-to-one with JSON
this sucks, though, because it means you can't use any types richer than what JSON offers, such as sets
-
on both frontend and backend, use a language like Haskell or Purescript which offers (semi-)automatic serialization of user-defined types
so we go with #2 and we deriving (ToJson, FromJson) on all our types, and now we get to easily pass rich objects between frontend and backend. great!
but that's only one part of the cruft we're trying to remove. what remains is the need to manually manage each api endpoint--to say, yep, we're adding an endpoint called /api/launch-nukes, and that should call the launchNukes() function, and the frontend to say, ok, we want backend to call launchNukes(), so let's ping /api/launch-nukes
in my head, the ideal is something like this. on my backend modules, wherever i define a top-level function returning IO, i can slap the word apidef in front; this allows frontend to call it with apicall. something like this:
-- backend
apidef launchTheNukes :: NukeLaunchRequest -> IO (Either String ())
-- frontend
do
-- in IO
response <- apicall Backend.launchTheNukes nukeLaunchRequest
case (response :: SomeKindOfHttpResponse (Either String ())) of
Ok (Right ()) -> -- success
_ -> -- failure
of course ideally this wouldn't be a language feature itself, but rather something built out of some more-general language feature
i don't think implementing this on a language like purescript as a third-party static-time transformation would be prohibitively difficult, but it does sound janky as hell to me
