[swift-server-dev] Prototype of the discussed HTTP API Spec

Johannes Weiss johannesweiss at apple.com
Wed May 31 09:07:00 CDT 2017


> On 31 May 2017, at 2:50 pm, Helge Heß via swift-server-dev <swift-server-dev at swift.org> wrote:
> On 31 May 2017, at 15:20, Johannes Weiss via swift-server-dev <swift-server-dev at swift.org> wrote:
>> Running everything on one thread with an async-only API is pretty much exactly what Node.js has as its only implementation and you might find that the APIs look remarkably similar [1].
> Sorry if this is a little off-topic, but I just wanted to mention that I think neither is really true.
> I’m not completely sure, but I think the Node.js HTTP implementation actually runs on multiple threads, it is just the user level JavaScript stack that is single threaded (I think it sparks CPU-count threads). May be wrong on that ;-)


> Also the API of Node.js is nothing like the proposal, unless you are saying that ‘callbacks’ are the main criteria for Equatable here. Node.js is not built on simple callbacks like the proposal, but adds the concept of streams (two variants, pull and push). Node push streams are a little like GCD channels. But streams add quite a few more features, including piping, transformations, buffers and automatic back pressure handling.

well, the basic API is similar I think

response writing:
	• response.writeHead(statusCode[, statusMessage][, headers])
	• response.writeContinue()
	• response.write(chunk[, encoding][, callback])
	• response.addTrailers(headers)
	• response.end([data][, encoding][, callback])

getting a request (get the request and a response (writer)):
	Event: 'request'#
		• request <http.IncomingMessage>
		• response <http.ServerResponse>

and the IncomingMessage (HTTPRequestHead for us) has headers, http version and stuff but not the body.

Instead of returning a closure, you register a handler in the request à la

--- SNIP ---
--- SNAP ---

which is reasonably close to

--- SNAP ---
    return .processBody { (chunk, stop) in
        switch chunk {
            case .chunk(let data, let finishedProcessing): /* like request.on('data', ...) */
                res.writeBody(data: data) { _ in
            case .end: /* like request.on('end') */
                stop = true /* don't call us anymore */
--- SNAP ---

don't you think? To me it looks quite straightforward to port a Node HTTP app to the proposal we're discussing.

But I do agree that we don't have streams. I thought about something like that but I thought that's too much just for HTTP. If we want to have a more general streaming mechanism, we should probably discuss that in the Transport/Networking meetings, no?

> That is why I said since the beginning that I’m more interested in how the API for the body stream will look like (as this affects sockets as well as HTTP). Now we essentially get separate APIs for the same thing ...

I do agree with you here. But the networking group basically hasn't happened yet so I was proposing something here as we happened to have an implementation that works.

> While I’d love to have a nice streaming framework like the one Node has built right into Swift, maybe just some extension of GCD channels would do (if you don’t want to go the full stream-everything approach Noze.io does), but I understand that this is a little out of scope and probably impossible to agree on ;-) Doesn’t matter too much as you can put adapters on top of the stuff.


-- J

> Hence: off-topic, srz, couldn’t resist.
> hh
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev

More information about the swift-server-dev mailing list