elm / http

Make HTTP requests in Elm
https://package.elm-lang.org/packages/elm/http/latest
BSD 3-Clause "New" or "Revised" License
154 stars 46 forks source link

Must `Request` be an opaque type? #1

Closed rgrempel closed 7 years ago

rgrempel commented 8 years ago

I was looking at my package rgrempel/elm-http-decorators to see what needed to be updated for the new version of http. Two of the functions are now obsolete, because http now itself does what they did. The third function addCacheBuster, needs some changes. Here's a link to the implementation, for reference:

https://github.com/rgrempel/elm-http-decorators/blob/1.0.2/src/Http/Decorators.elm#L64-L93

Basically, it takes the send function from Http and wraps it so that a cache-busting parameter gets added to the URL. As currently implemented, this involves taking a Request as a parameter, extracting the URL, constructing a new Request with a modified URL, and then passing it along to the "real" send function.

The difficulty, of course, is that Request is now an opaque type. Thus, if I ask for a Request in my function signature, I can't extract the URL.

The obvious workaround, of course, is to not ask for a Request as a parameter. Instead, I can ask for the various things that make up a request (I suppose I would more or less copy the structure of RawRequest), and then use that to construct a request (by passing it to the request function, after making the necessary modifications).

That would clearly work, but it would be awkward.

Of course, the elegance (or lack thereof) of my little function makes no difference in the big scheme of things, and would be no good reason (by itself) to change anything. However, I'm wondering whether there might be other use cases that would benefit if Request were less opaque. At the moment, given a Request, there is nothing you can do to "analyze" it. It seems possible that there would be other useful convenience functions of the form Request a -> Request a, which the opacity of Request makes, well, awkward.

Of course, I understand that there are sometimes very good reasons to have opaque types.

rgrempel commented 8 years ago

I have now modified my elm-http-decorators module in order to expose a transparent RawRequest type, and various functions that work with a RawRequest rather than a Request.

So, it certainly is possible to work around the opacity of Request. However, I thought that seeing the code needed to do so might be helpful in thinking about whether Request needs to be opaque.

evancz commented 7 years ago

Making types like this opaque is best practice. It means the core implementation can change, but no one's code changes. If you want info from inside, it's best to create a function that spits it out is some format, that way the function can be updated even if the internals change.

That said, I think makes sense to build your own opaque Request type. I believe that's what http://package.elm-lang.org/packages/lukewestby/elm-http-builder/latest does, and I think it's fine for alternatives to not interoperate with each other directly. If the alternative is better, I don't see a strong reason to use both.

rgrempel commented 7 years ago

Yes, that is what my RawRequest also does. I'll see if I can actually use HttpBuilder instead, for the sake of interop.