On Wednesday, January 18, 2017 at 7:03:37 AM UTC, Max Goldstein wrote: > > I came upon the idea that the client (that's you) will provide a type > alias for each resource's attributes (and perhaps other crucial > information), and I could generate code that would retrieve resources of > those types. Generating code also allows the tool to create JSON encoders > and decoders, a common pain point. >
I've been doing something very similar and it is proving very worthwhile, so I would encourage you to pursue this. In my case, I have a data model and a mapping of that onto a set of REST endpoints. The model that describes this is implemented Java and I use a (horrible) templating library called StringTemplate to do codegen from it. For Elm, I output one (big) file called Model.elm, that gives me the data model mapped onto Elm, and encoders and decoders for it. Then for each grouping of endpoints (each service implemented in Java provides the grouping) I generate one Elm file that implements the Http logic for the service. I haven't open sourced this, but it might not be of much use to you anyway. Each service requires a set of callback functions to be passed in - one for each endpoint, plus one for each endpoint when it results in an error, plus a default error handler for cases when the endpoint specific error handler doesn't process the error. The service also defines a set of convenience functions for triggering a call to the service. You nest the services update function inside yours and pass it the callbacks. Putting all the callback functions together in a record is a design choice I might re-think for something less monolithic. Anyway, here is an example of using it. cseCallbacks : CSE.Callbacks Model Msg cseCallbacks = let default = CSE.callbacks -- Default no-op callbacks so you only specify what you need. in { default | retrieveWithContainerBySlug = retrieveWithContainerBySlug , error = error } update : Msg -> Model -> ( Model, Cmd Msg ) update action model = case (Debug.log "Client.State" action) of CSEApi action_ -> CSE.update cseCallbacks action_ model -- Nesting the services update function. SelectLocation location -> ( model, CSE.invokeRetrieveWithContainerBySlug CSEApi location ) -- Invoking a service helper function. Another possibility would be to use an API description meta-data such as Swagger. A Swagger codegen for Elm could easily output something useable. Its definitely worth doing - the current project I am working on I have about 6K lines of Elm generated, all at practically zero effort (well, except the days and days I spent setting up the code generator, but that is effort I can re-use over and again). Project before that was about 4K lines. These were not huge APIs, maybe 4 or 5 entity types. I am planning to move my codegen templates over from StringTemplate to Elm at some point. Now that I have server side rendering with Elm working. I defined a static Program type like this for it: type alias StringProgram = Program Value String Never https://github.com/rupertlssmith/elm-server-side-renderer/blob/master/src/ServerSide/Static.elm#L24 I think Elm will be well suited to writing code generators - in a manner similar to how it 'codegens' Html. You can design a set of functions for constructing the component parts of the output language you are working with. Elm is good for doing complex AST manipulation and it can be set up to guarantee correctly formed output. Code generation of Elm in Elm will be a mind bender. -- You received this message because you are subscribed to the Google Groups "Elm Discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.