caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Rudi Grinberg <rudi.grinberg@gmail.com>
To: Dario Teixeira <dario.teixeira@nleyten.com>
Cc: caml-list <caml-list@inria.fr>
Subject: Re: [Caml-list] Functorising over Cohttp's backends
Date: Mon, 29 Aug 2016 11:39:45 -0400	[thread overview]
Message-ID: <20160829153945.424bhlwpk7pmm6em@rgcaml.localdomain> (raw)
In-Reply-To: <f80651ae31d96eac1115bf124d97eac4@nleyten.com>

The Cohttp API at its present state doesn't really offer a good abstraction for
creating backend independent HTTP clients and servers.

Luckily, the request and response types are backend independent. And so is the
http body type if you aren't streaming. This means that you can fairly easily
create a light application specific abstraction for yourself.

This means is that if you'd like to provide a backend independent server,
you should just worry about providing 2 functions of the type:

open Cohttp

val lwt : Request.t -> Body.t -> (Response.t * Body.t) Lwt.t
val async : Request.t -> Body.t -> (Response.t * Body.t) Deferred.t

and perhaps provide some light wrappers for turning these into full blown
cohttp servers in a backend dependent way.

With this technique, Cohttp's API will only help you as far as manipulating
request, response, and body values. This can often be enough for simple servers.
But in cases where it's not, such as when you need access to the client FD for
example Going back to implementing those 2 functions, you will need to cook up
your own abstractions on top.

Now going back to implementing the 2 functions mentioned above. For any non
trivial server, you will need to find a way to share code between your Async and
Lwt implementation. This is where it's common to use standard techniques such as
functors. But that's a topic you know about just as much as I do :P

To summarize, it's unfortunate that Cohttp doesn't provide a real server (or
client) abstraction. But it's kind of hard to do without making a wrapper that
tries to abstract away the differences between different backends. Hiding away
the details of Async and Lwt was always an anti-goal for Cohttp anyway.

Cheers,

Rudi.


On 08/29, Dario Teixeira wrote:
>Hi,
>
>Suppose I have a function "make_callback" which creates a callback
>ready to be given to Cohttp's Server.make. Here's its signature:
>
> type callback =
>   Cohttp_lwt_unix.Server.IO.conn * Cohttp.Connection.t ->
>   Cohttp.Request.t ->
>   Cohttp_lwt_body.t ->
>   (Cohttp.Response.t * Cohttp_lwt_body.t) Cohttp_lwt_unix.Server.IO.t
>
> val make_callback: unit -> callback
>
>Note that it's tied to the Lwt+Unix instantiation of Cohttp. Now,
>I wish to make it more generic, so it can be used with the Async
>backend, for instance.
>
>There's more to it than just using a functor for abstracting over the
>IO monad, unfortunately. In particular, the connection type and the
>body are also backend-dependent. Anyway, Cohttp's API is notoriously
>hard to navigate. Is the generic signature I'm looking for already
>defined somewhere, or are the backends so distinct that I might
>as well forget about functorising the interface and thus force the
>Lwt+Unix backend on my API? (It's the only backend I use myself...)
>
>Thanks in advance!
>Best regards,
>Dario Teixeira
>
>
>-- 
>Caml-list mailing list.  Subscription management and archives:
>https://sympa.inria.fr/sympa/arc/caml-list
>Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>Bug reports: http://caml.inria.fr/bin/caml-bugs

  reply	other threads:[~2016-08-29 15:39 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-29 13:53 Dario Teixeira
2016-08-29 15:39 ` Rudi Grinberg [this message]
2016-08-29 18:42   ` Dario Teixeira
2016-08-29 21:51     ` Daniel Bünzli
2016-08-30  9:08       ` Malcolm Matalka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160829153945.424bhlwpk7pmm6em@rgcaml.localdomain \
    --to=rudi.grinberg@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=dario.teixeira@nleyten.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).