Recommended Channel Message Shape?

The Phoenix Channels page gives the following line in the trivial chat demo:

channel.push("new_msg", {body: chatInput.value})

So the trivial message has the content in the body key. I figure this is just a demo, but I am thinking of the standard JSON API usage of data, errors, and metadata. Is this what others are doing? Are there any reasons not to use this approach?

I am currently changing ibGib from a server-rendered workflow to a more dynamic one built on top of channels. The structure is very much akin to a command/event bus, so the user executes a command which may or may not execute remotely on the server. If it does execute remotely I create and send a command message with the relevant command info, and eventually I will get back zero or more event message(s). I know I can just roll my own, but I’m looking to see what others are actually using in real-world applications. :earth_americas: :eyes:

I’ve actually been using my views to render channel messages. This means I don’t have to have any additional code to present data in channels that I already present in controllers. I also create views for any cases specific to my channels. Basically, anything that is shown to the client goes through a view at some point, and there is no presentation logic in controllers or channels.

1 Like

Ah, that sounds like a :cool: approach I hadn’t thought of. It makes me think of two questions:

  1. What is the shape of the channel message that gets rendered through the view.
  2. What is the shape of the channel message going the other direction, from the client to the server?

Also, in my case right now, I am no longer presenting a new page after commands, i.e. there is only a single page load and the front end is basically a SPA. So I’m using the channel as a message bus to pass commands and events back and forth between the client and server. :computer: :eyes: :desktop:

Interesting. Yeah, IMHO you should still use views as your presentation layer (in this case, they will be JSON views).

To answer your questions:

I would determine something standard, and then stick with it. I’m doing something like this:

{
  "posts": [
    {
      "id": 1,
      "title": "My first post",
      ...
    }
  ]
}

And then for errors:

{
  "errors": {
    "title": [{"message": "is required"}]
  }
}

And then these are paired with HTTP response codes like 201 Created for a successful insertion, 400 Bad Request when there are validation errors, etc. (which obviously does not apply in your use-case).

Nearly identical to what you receive from the client, e.g.

{
  "title": "My first blog post"
}

You’ll want these shapes to match closely so that you can easily use data from the server as models in your Javascript app, and then simply send back the modified model to update data.

I’m curious as to why you’re using channels this way, as opposed to using RESTful HTTP routes in combination with websockets. Is this some sort of game or something?

1 Like

Ah, so you are going with the approach I was originally thinking of, which is have the intrinsic data just be the message itself, i.e. not a structured message like data, errors, metadata. That is not to say that your data doesn’t have a structure, rather that it isn’t doing a metadata-style structure. That is what I’m leaning towards, but I’m wondering what are specific benefits of adding the extra layer of structure as in the JSON API standard. This is not the JSON specification itself for using JSON, it’s more of a convention of how to structure JSON requests/responses. I’m not thinking of going nearly so structured as that, like using include and resources mentioned there, etc. But I’m wondering how others (like yourself :smile:) are doing it.

Oh goodness…now I’ll talk your :ear: off. Feel free to skim! It’s basically like a game, but I’m using d3 on the front end, since my app is really about data creation/visualization. The current version, at www.ibgib.com, is completely server-rendered and static (insofar as the data is concerned). I build up the data behind the d3 rendering on the server and I send this data to the client all when the page loads. But now, in making it more dynamic it’s a completely different ballgame. :baseball:

The entire structure of ibGib is about immutable data constructs. To avoid duplicating the engine’s code, this only resides on the server. So on the client side, I’m not modifying any models. It is very much like a CQRS or nowadays a “reactive” type architecture. I put commands on a command/event message bus (the socket) that get processed somewhere (right now on the server), and these commands create immutable data structures (called ibGib). These ibGib on the server will spawn events that will get propagated to the client on that same message bus (same socket, possibly different channels).

Interestingly, I definitely have to handle validation errors, especially since I have spent so much time learning about security as an Air Force contractor. Always validate everything at every level. That said, I had not thought about associating http response codes and I think I may end up doing that… :thinking:

I actually really like this concept. The best way to figure out how to format these types of commands is probably to just start playing around and then be willing to refactor quickly. I’d imagine you’ll be able to come up with some cool command propagation architecture that takes advantage of pattern matching.

I didn’t mean not handling validation errors, I just meant that you won’t have true HTTP response codes if you’re working exclusively over websockets. You could easily just add the codes to your JSON structure though.

1 Like