HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

WebSocket-based API library in Racket

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
websocketlibrarybasedapiracket

Problem

I've developed a library in (typed) Racket that wraps a WebSocket-based API. The API itself is very simple—it operates via a series of three-letter commands optionally followed by a JSON-encoded payload.

The simple library itself provides a series of small abstractions over interfacing with the raw WebSocket data:

  • The connection/handshaking sequence is handled automatically by the library itself. It notifies the client when the handshaking is complete via a synchronizeable event in the form of a semaphore.



  • It also automatically responds to ping commands to prevent the connection from timing out.



  • The send! and recv! functions automatically wrap/unwrap commands and JSON payloads so that parsing doesn't need to be done manually.



  • The received commands are queued by the library until read so that they can be handled on-demand.



I think the implementation is fairly solid, but I'd like to know if anything could be improved. Anything from simple readability adjustments to proposed structural changes would be appreciated.

```
#lang typed/racket/base

(provide
(prefix-out fchat- (combine-out request-ticket!
connect
send!
recv!
close!
conn-character))
FChatConn
fchat-conn?)

;; ---------------------------------------------------------------------------------------------------

(require racket/match
racket/list
typed/racket/async-channel
typed/net/http-client
typed/net/uri-codec
fchat/typed/json)

(require/typed net/url-structs
[#:struct path/param ([path : (U String 'up 'same)]
[param : (Listof String)])
#:extra-constructor-name make-path/param]
[#:struct url ([scheme : (Option String)]
[user : (Option String)]

Solution

Well, take this with a grain of salt, as I have a lot less knowledge of
(typed) Racket; that said it's very readable, the comments are nice and
you have a few test, looks good I think.

I'd suggest a few really minor things:

-
Consistency: At some points you use (list (cons ..., at others the
backquote syntax; I'd probably use only one of them.

-
Configurability: The URLs and paths are hardcoded at the moment;
moving them out into their own definitions would make it a bit nicer,
same for the ports. If the only difference for debug is the port,
I'd say use a port parameter with default value instead (more
reusable).

-
Style: This SO answer captures
this quite well, basically that let is a bit more portable across
Lisps and also captures the actual lexical nesting quite well. See comments.

Context

StackExchange Code Review Q#75647, answer score: 2

Revisions (0)

No revisions yet.