Advanced Trade Feedback

After integrating against WebSockets I have some suggestions that would have made my life easier.

The documentation doesn’t actually show the schema format of the messages coming from CoinBase. In my opinion, the schema doesn’t make a whole lot of sense and is a bit painful to work with.

As an example for tickers
The docs say to expect a message that looks like

{
   "type":"ticker",
   "sequence":29912240,
   "product_id":"BTC-USD",
   "price":"40552.26",
   "volume_24h":"0.43526841",
   "low_24h":"40552.26",
   "high_24h":"40662.06"
}

This is fine. But this isn’t really what comes over the wire.
Instead you get

{
	"channel": "ticker",
	"client_id": "",
	"timestamp": "2022-11-22T04:23:54.618364894Z",
	"sequence_num": 0,
	"events": [{
		"type": "snapshot",
		"tickers": [{
			"type": "ticker",
			"product_id": "BTC-USD",
			"price": "15801.22",
			"volume_24_h": "39927.87557223",
			"low_24_h": "15460",
			"high_24_h": "16257",
			"low_52_w": "15460",
			"high_52_w": "59526.51",
			"price_percent_chg_24_h": "-2.32280685270057"
		}]
	}]
}

What’s weird for me is an event contains a type (snapshot or update) and then a list of the actual events within the event. It would make a lot more sense (and be easier to work with) if it were flatter like this

{
	"channel": "ticker",
	"client_id": "",
	"timestamp": "2022-11-22T04:23:54.618364894Z",
	"sequence_num": 0,
	"events": [
		{
			"event_type": "snapshot",
			"type": "ticker",
			"product_id": "BTC-USD",
			"price": "15801.22",
			"volume_24_h": "39927.87557223",
			"low_24_h": "15460",
			"high_24_h": "16257",
			"low_52_w": "15460",
			"high_52_w": "59526.51",
			"price_percent_chg_24_h": "-2.32280685270057"
		},
		{
			"event_type": "update",
			"type": "ticker",
			"product_id": "BTC-USD",
			"price": "15801.11",
			"volume_24_h": "39927.87557223",
			"low_24_h": "15460",
			"high_24_h": "16257",
			"low_52_w": "15460",
			"high_52_w": "59526.51",
			"price_percent_chg_24_h": "-2.32348683128742"
		}
	]
}

In this format, it allows the client to iterate over each one without so many nested loops and temporary states to keep track of the “event type”

On a side note, I don’t know why exchanges are using JSON over WebSockets anymore. I’ve not found one that’s easy to work with. When open-source technologies like gRPC exist, designing these WebSocket API’s doesn’t make sense. With a gRPC endpoint, developers can have a fully working and very high-performance client up and running in minutes without reading any documentation. gRPC supports request and response style (REST) or bidirectional style communication (WebSocket). It would most likely reduce the overhead for the exchange, too, as encoding and decoding can often be less compute and memory intense than JSON and will consume a fraction of the bandwidth to send the messages.

gRPC doesn’t really work in web browsers which doesn’t make it a great option for Coinbases own website. Still, Protobuf also defines a JSON representation and often without too much extra effort, a server can offer a standard HTTP API, JSON over WebSocket AND a gRPC endpoint sharing the same implementation, all documented by the proto files.

This seems like a no-brainer for a new high-performance API in 2022.

All things being said, even though I think the WebSocket schemas could be better. Advanced trade WebSockets have been relatively easy to work with. Especially compared to the competition. Great work to the team at Coinbase!

3 Likes