Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit 63addf1

Browse files
committed
Apply suggestions from code review
Co-authored-by: Jye Cusch <[email protected]> Simplify project so it doesn't need an update to the nitric.yaml config. Simplify project so it doesn't need an update to the nitric.yaml config. handle errors and add consistency between guides
1 parent e0be643 commit 63addf1

File tree

3 files changed

+115
-105
lines changed

3 files changed

+115
-105
lines changed

docs/guides/go/realtime-messaging.mdx

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
---
2-
title_seo: Building your first WebSocket Application with Go and Nitric
32
description: Use the Nitric framework to easily build and deploy Go WebSocket applications for AWS.
43
tags:
54
- Realtime & Websockets
65
- Key Value Store
76
---
87

9-
# Building your first WebSocket Application with Nitric
8+
# Building a chat app in Go with WebSockets and Nitric
109

1110
## What we'll be doing
1211

13-
1. Use Nitric to create a WebSocket endpoint
12+
1. Use Nitric to create a WebSocket API
1413
2. Manage WebSocket connections using a Key-Value store
1514
3. Handle WebSocket events:
1615
- Register connections on connect
@@ -23,20 +22,20 @@ tags:
2322

2423
- [Go](https://go.dev/dl/)
2524
- The [Nitric CLI](/get-started/installation)
26-
- An [AWS](https://aws.amazon.com) account
25+
- An [AWS](https://aws.amazon.com) account (optional)
2726

2827
## Getting started
2928

3029
We'll start by creating a new project for our WebSocket application.
3130

3231
```bash
33-
nitric new my-websocket-app go-starter
32+
nitric new websocket-app go-starter
3433
```
3534

3635
Next, open the project in your editor of choice.
3736

3837
```bash
39-
cd my-websocket-app
38+
cd websocket-app
4039
```
4140

4241
Make sure all dependencies are resolved:
@@ -69,9 +68,9 @@ If everything is working as expected, you can now delete all files/folders in th
6968

7069
## Building the WebSocket Application
7170

72-
Let's begin by setting up the WebSocket application. First, create a new folder called `websockets` within the services directory. Inside this folder, add a file named `main.go`, and include the following code:
71+
Let's begin by setting up the WebSocket application. Add a file named `main.go` to your 'services/websockets' folder, and include the following code:
7372

74-
```go
73+
```go title:services/websockets/main.go
7574
package main
7675

7776
import (
@@ -84,7 +83,7 @@ import (
8483
)
8584

8685
func main() {
87-
// Create a WebSocket endpoint named "public".
86+
// Create a WebSocket API named "public".
8887
ws := nitric.NewWebsocket("public")
8988

9089
// Initialize a KV store named "connections" with Get, Set, and Delete permissions.
@@ -98,8 +97,8 @@ func main() {
9897

9998
Here we're creating:
10099

101-
- A [WebSocket](/websockets) endpoint named `public`
102-
- A [Key-Value store](/keyvalue) named `connections` to track WebSocket connections
100+
- A [WebSocket](/websockets) API named `public`
101+
- A [Key-Value store](/keyvalue) named `connections` to track client connections
103102

104103
From here, let's add some features to that function that allow us to manage connections and broadcast messages.
105104

@@ -112,10 +111,11 @@ From here, let's add some features to that function that allow us to manage conn
112111

113112
```go
114113
ws.On(websockets.EventType_Connect, func(ctx *websockets.Ctx) {
115-
err := connections.Set(context.TODO(), ctx.Request.ConnectionID(), map[string]interface{}{
114+
err := connections.Set(context.Background(), ctx.Request.ConnectionID(), map[string]interface{}{
116115
"connectionId": ctx.Request.ConnectionID(),
117116
})
118117
if err != nil {
118+
fmt.Println("Error storing connection ID in KV store:", err)
119119
return
120120
}
121121
})
@@ -125,8 +125,9 @@ ws.On(websockets.EventType_Connect, func(ctx *websockets.Ctx) {
125125

126126
```go
127127
ws.On(websockets.EventType_Disconnect, func(ctx *websockets.Ctx) {
128-
err := connections.Delete(context.TODO(), ctx.Request.ConnectionID())
128+
err := connections.Delete(context.Background(), ctx.Request.ConnectionID())
129129
if err != nil {
130+
fmt.Println("Error deleting connection ID in KV store:", err)
130131
return
131132
}
132133
})
@@ -136,8 +137,9 @@ ws.On(websockets.EventType_Disconnect, func(ctx *websockets.Ctx) {
136137

137138
```go
138139
ws.On(websockets.EventType_Message, func(ctx *websockets.Ctx) {
139-
connectionStream, err := connections.Keys(context.TODO())
140+
connectionStream, err := connections.Keys(context.Background())
140141
if err != nil {
142+
fmt.Println("Error retrieving connection keys from KV store:", err)
141143
return
142144
}
143145

@@ -154,8 +156,9 @@ ws.On(websockets.EventType_Message, func(ctx *websockets.Ctx) {
154156
}
155157

156158
message := fmt.Sprintf("%s: %s", senderId, ctx.Request.Message())
157-
err = ws.Send(context.TODO(), connectionId, []byte(message))
159+
err = ws.Send(context.Background(), connectionId, []byte(message))
158160
if err != nil {
161+
fmt.Println("Error sending message to connection ID", connectionId, ":", err)
159162
return
160163
}
161164
}
@@ -167,7 +170,7 @@ ws.On(websockets.EventType_Message, func(ctx *websockets.Ctx) {
167170
<details>
168171
<summary>Your code should look like this:</summary>
169172

170-
```go
173+
```go title:services/websockets/main.go
171174
package main
172175

173176
import (
@@ -188,24 +191,27 @@ func main() {
188191

189192
// Handle new WebSocket connections by storing the connection ID in the KV store.
190193
ws.On(websockets.EventType_Connect, func(ctx *websockets.Ctx) {
191-
err := connections.Set(context.TODO(), ctx.Request.ConnectionID(), map[string]interface{}{
194+
err := connections.Set(context.Background(), ctx.Request.ConnectionID(), map[string]interface{}{
192195
"connectionId": ctx.Request.ConnectionID(),
193196
})
194197
if err != nil {
198+
fmt.Println("Error storing connection ID in KV store:", err)
195199
return
196200
}
197201
})
198202

199203
ws.On(websockets.EventType_Disconnect, func(ctx *websockets.Ctx) {
200-
err := connections.Delete(context.TODO(), ctx.Request.ConnectionID())
204+
err := connections.Delete(context.Background(), ctx.Request.ConnectionID())
201205
if err != nil {
206+
fmt.Println("Error deleting connection ID in KV store:", err)
202207
return
203208
}
204209
})
205210

206211
ws.On(websockets.EventType_Message, func(ctx *websockets.Ctx) {
207-
connectionStream, err := connections.Keys(context.TODO())
212+
connectionStream, err := connections.Keys(context.Background())
208213
if err != nil {
214+
fmt.Println("Error retrieving connection keys from KV store:", err)
209215
return
210216
}
211217

@@ -222,8 +228,9 @@ func main() {
222228
}
223229

224230
message := fmt.Sprintf("%s: %s", senderId, ctx.Request.Message())
225-
err = ws.Send(context.TODO(), connectionId, []byte(message))
231+
err = ws.Send(context.Background(), connectionId, []byte(message))
226232
if err != nil {
233+
fmt.Println("Error sending message to connection ID", connectionId, ":", err)
227234
return
228235
}
229236
}
@@ -239,36 +246,31 @@ Do a quick `go mod tidy` to make sure all new dependencies are resolved.
239246

240247
## Ok, let's run this thing!
241248

242-
Now that you have your WebSocket application defined with handlers for each event, it's time to test it locally. Update your `nitric.yaml` to point to the service at `websockets/main.go`:
243-
244-
```yaml
245-
services:
246-
- match: websockets/*
247-
runtime: go
248-
start: go run ./$SERVICE_PATH
249-
```
249+
Now that you have your WebSocket application defined with handlers for each event, it's time to test it locally.
250250

251251
```bash
252252
nitric start
253253
```
254254

255-
Once it starts, the application will be ready to accept WebSocket connections. You can use a WebSocket client like Postman or any other WebSocket tool to test the application. Alternatively, you can use the [Nitric Dashboard](/get-started/foundations/projects/local-development#local-dashboard).
255+
Once it starts, the application will be ready to accept WebSocket connections that you can easily test with the [Nitric Dashboard](/get-started/foundations/projects/local-development#local-dashboard). You can find the URL to the dashboard in the terminal running the Nitric CLI, by default, it is set to - http://localhost:49152.
256+
257+
![websocket dashboard](/docs/images/guides/realtime-messaging/dashboard.png)
256258

257-
We will keep it running for our tests.
259+
The dashboard will show you the WebSocket URL and allow you to connect as a client to send, receive and monitor messages.
258260

259261
## Deploy to the cloud
260262

261-
At this point, you can deploy what you've built to any of the supported cloud providers. To do this, start by setting up your credentials and configuration for [AWS](/providers/pulumi/aws).
263+
At this point, you can deploy what you've built to any of the supported cloud providers. In this example we'll deploy to AWS. Start by setting up your credentials and configuration for the [nitric/aws provider](/providers/pulumi/aws).
262264

263-
Next, we'll need to create a `stack`. A stack represents a deployed instance of an application, which is a key value store of resources defined in your project. You might want separate stacks for each environment, such as stacks for `dev`, `test`, and `prod`. For now, let's start by creating a `dev` stack.
265+
Next, we'll need to create a `stack file` (deployment target). A stack is a deployed instance of an application. You might want separate stacks for each environment, such as stacks for `dev`, `test`, and `prod`. For now, let's start by creating a file for the `dev` stack.
264266

265267
The `stack new` command below will create a stack named `dev` that uses the `aws` provider.
266268

267269
```bash
268270
nitric stack new dev aws
269271
```
270272

271-
Continue by checking your stack file `nitric.dev.yaml` and adding in your preferred region. Let's use `us-east-1`.
273+
Edit the stack file `nitric.dev.yaml` and set your preferred AWS region, for example `us-east-1`.
272274

273275
### AWS
274276

@@ -277,7 +279,7 @@ Continue by checking your stack file `nitric.dev.yaml` and adding in your prefer
277279
costs associated with deployment.
278280
</Note>
279281

280-
We called our stack `dev`. Let's try deploying it with the `up` command:
282+
Let's try deploying the stack with the `up` command:
281283

282284
```bash
283285
nitric up

0 commit comments

Comments
 (0)