As I stated in one of my earlier articles, Go is one of the most popular programming languages in the world right now. Due to its robustness and performance, Go has become the 'Go'to choice of many developers (Yes, That was an intended pun)
Why do we need this?
The WebSocket API is a way of communication between different event-driven services. This is an open two way communication between the API and the consumer client where we can send messages to the server once connected and then receive a response from the server. This usually tends to be more performant than usual HTTP REST API communication. One common use case for this type of service is where you have to get updated data frequently. A few examples can be getting the prices of cryptocurrencies (they change literally in seconds), getting the updated score of a cricket/football match, etc.
I've given you a brief overview of WebSockets, let's begin with our article.
So let's get started.
Create Websocket API in Golang
First, let us create an empty folder where our code will reside.
I'm calling it websocket-api
Now open this empty folder directory in your favorite code editor. I'll be using VS Code for today,
Now we will create a new file called main.go.
Now open the terminal/command prompt in this directory. In this case, I will use the integrated terminal with VS Code.
Run this command,
go mod init YOUR_APP_NAME
So in our case, my command will be
go mod init websocket-api
After running it, you will see the above output.
Also, there will be a file generated called go.mod
As you can see, it has the name of the app that we provided in the command and the go version for our application.
Now let's go to main.go.
As we know, everything in go needs to be in a package, so we will write "package main" at the top of the file.
Now we will write a setupRoutes function and import statement at the top of the file.
We will be importing "net/http", "github.com/gorilla/websocket" & "fmt"
import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)
func setupRoutes() {
http.HandleFunc("/", homePage)
http.HandleFunc("/ws", wsHandler)
}
Now we will write a method called homepage & another method called wsHandler
func homePage(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello")
}
func wsHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
defer conn.Close()
reader(conn)
}
As you can see, our wsHandler method is the one that will handle the WebSocket connections
Now we will write the reader method
func reader(conn *websocket.Conn) {
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
fmt.Println(err)
}
fmt.Println(string(p))
msg := "You sent : " + string(p)
if err := conn.WriteMessage(messageType, []byte(msg)); err != nil {
fmt.Println(err)
}
}
}
Inside the reader method, it receives a websocket connect as a parameter and tries to read the incoming message from the connection. We will do our processing here, but for now, I've just printed in the console.
Now if you see the "msg" variable, I have created a string "you sent : " and then appended the text we got.
Here we can configure our response, whatever we want to send to the user back, and in the next line, we are just writing that message using our connection object.
Now all that's left is just to wire it all up in a main function
func main() {
fmt.Println("hello")
setupRoutes()
http.ListenAndServe(":8181", nil)
}
Here I have configured my app to run on the 8181 port. You can pick any port that's available on your machine.
So your entire main.go file should look something like this
package main
import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{}
func setupRoutes() {
http.HandleFunc("/", homePage)
http.HandleFunc("/ws", wsHandler)
}
func homePage(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello")
}
func wsHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
defer conn.Close()
reader(conn)
}
func reader(conn *websocket.Conn) {
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
fmt.Println(err)
}
fmt.Println(string(p))
msg := "You sent : " + string(p)
if err := conn.WriteMessage(messageType, []byte(msg)); err != nil {
fmt.Println(err)
}
}
}
func main() {
fmt.Println("hello")
setupRoutes()
http.ListenAndServe(":8181", nil)
}
Now since we are using a package as well we need to run this command
go get github.com/gorilla/websocket
This will get your websocket package
Now let's try to run it. So for that, we will open our terminal in the same directory again and run the following command
go run main.go
It prints hello, it means our API is running now.
Now let's test it on postman.
Click on New in postman rest client app
From the above menu pick, Websocket request
In the Url field, enter the localhost URL with the port number that you configured in the code
My URL is
localhost:8181/ws
After entering it, press connect. You should see something like this
It means a connection has been established from our WebSocket API.
Now in the textbox above, type any message and send.
As you can see, as soon as I clicked send, I got the reply from the server saying, 'You sent : '. This was the string that we made in our code.
Now you have successfully created a WebSocket API and tested it.
For simplicity, I'm sending the string messages, but you can easily send any JSON objects and work on input as per your requirements.
Summary
In today's article, we have seen how to create WebSocket APIs in golang.
If you wish to see the code, please click here!