Introduction
InfluxDB is an open-source time-series database specifically suitable for IoT projects, cloud-native services, and more. The package is written in the Golang programming language. You can use it for data exploration, data visualization, and to run dashboard applications.
While InfluxDB comes with great tools for storing, querying, and processing data, you can still use its API libraries inside your Golang project. This enhances flexibility when working with the time series data since you can pass it through custom functions that may not be available in the InfluxDB codebase.
In this guide, you'll implement the InfluxDB database functions with Golang on your Ubuntu 20.04 server.
Prerequisites
To proceed with this guide, make sure you have the following:
1. Create an InfluxDB Database
In this tutorial, you'll set up an InfluxDB database and insert some time-series data for testing purposes. Later, you'll query your InfluxDB server via a Golang script to retrieve or insert points to the database.
Connect to your server to complete the following steps:
Log in to the InfluxDB server. Replace admin
with the name of your InfluxDB super-user
account. Pass the -password ''
option to allow the following influx
command to prompt you for a password.
$ influx -username 'admin' -password ''
Key in your password and press Enter to proceed. Next, execute the following statement to create a sample_db
database.
> CREATE DATABASE sample_db
Switch to the new sample_db
database.
> USE sample_db
Insert the following points into your sample_db
database under the power_usage
measurement. In this application, you're tracking the power loads for users in different homes where a solar system has been installed. In this step, you'll enter the data manually, but this data may originate from IoT devices installed in all homes requiring measurement tracking in a production environment.
> INSERT power_usage,client_id=100731,location=BRANSON current_load_in_amperes=0.2
> INSERT power_usage,client_id=800478,location=MIAMI current_load_in_amperes=0.1
> INSERT power_usage,client_id=907854,location=CHICAGO current_load_in_amperes=0.4
> INSERT power_usage,client_id=532681,location=CHARLESTON current_load_in_amperes=0.1
Query the power_usage
measurement to make sure the data is in place.
> SELECT "client_id", "location", "current_load_in_amperes" FROM power_usage
You should get the following output showing time-stamped data as you entered it in the sample_db
database.
time client_id location current_load_in_amperes
---- --------- -------- -----------------------
1638542140183389389 100731 BRANSON 0.2
1638542147803130270 800478 MIAMI 0.1
1638542155163864457 907854 CHICAGO 0.4
1638542162283179983 532681 CHARLESTON 0.1
Log out from the InfluxDB server.
> QUIT
2. Create a main.go
File
In this application, you'll create a main.go
file. This runs the main(...)
function that fires when you start the application.
Separate your source code files from the rest of the Linux files by creating a new project
directory.
$ mkdir project
Next, navigate to the project
directory.
$ cd project
Then, use nano
to open a new main.go
file.
$ nano main.go
Enter the following information into the main.go
file.
package main
import (
"net/http"
"encoding/json"
"fmt"
)
func main() {
http.HandleFunc("/power-consumptions", httpHandler)
http.ListenAndServe(":8080", nil)
}
func httpHandler(w http.ResponseWriter, req *http.Request) {
var err error
resp := map[string]interface{}{}
if req.Method == "POST" {
params := map[string]interface{}{}
err = json.NewDecoder(req.Body).Decode(¶ms)
if err != nil {
fmt.Fprintf(w, err.Error())
}
resp, err = createPoint(params)
}
if req.Method == "GET" {
resp, err = getPoints()
}
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
if err != nil {
fmt.Println(err.Error())
} else {
if err := enc.Encode(resp); err != nil {
fmt.Println(err.Error())
}
}
}
Save and close the main.go
file when you're through with editing.
In the above file, you've created a main()
function to listen for incoming HTTP requests on port 8080
. You've then redirected the request to the httpHandler()
function to determine the HTTP req.Method
. For POST
requests, you're calling a createPoint(params)
function, which you'll create in a new file later. This function accepts the JSON payload as an argument for the point that you want to create to the database.
Next, you're redirecting GET
requests to the getPoints()
function, which retrieves data from the database and returns a map.
3. Create an influxdb.go
File
You'll create a file to interact with your InfluxDB server in this step. This file contains two functions. You'll use the createPoint()
function to enter new points into the database and the getPoints()
function to retrieve entries from your power_usage
measurement.
Use nano
to create a new influxdb.go
file.
$ nano influxdb.go
Next, enter the following information into the influxdb.go
file. Replace const USERNAME
and const PASSWORD
with the correct authentication credentials for your InfluxDB server.
package main
import (
"github.com/influxdata/influxdb1-client/v2"
"time"
"errors"
)
const (
USERNAME string = "admin"
PASSWORD string = "EXAMPLE_PASSWORD"
DATABASE string = "sample_db"
)
func createPoint(params map[string]interface{}) (map[string]interface{}, error) {
influxClient, err := client.NewHTTPClient(client.HTTPConfig{
Addr: "http://localhost:8086",
Username: USERNAME,
Password: PASSWORD,
})
if err != nil {
return nil, err
}
bp, err := client.NewBatchPoints(client.BatchPointsConfig{
Database: DATABASE,
})
if err != nil {
return nil, err
}
clientId := params["client_id"].(string)
location := params["location"].(string)
currentLoadInAmperes := params["current_load_in_amperes"]
pt, err := client.NewPoint("power_usage", map[string]string{"client_id": clientId, "location": location},
map[string]interface{}{"current_load_in_amperes": currentLoadInAmperes},
time.Now())
if err != nil {
return nil, err
}
bp.AddPoint(pt)
err = influxClient.Write(bp)
if err != nil {
return nil, err
}
resp := map[string]interface{}{"data" : "Success"}
return resp, nil
}
func getPoints() (map[string]interface{}, error) {
influxClient, err := client.NewHTTPClient(client.HTTPConfig{
Addr: "http://localhost:8086",
Username: USERNAME,
Password: PASSWORD,
})
if err != nil {
return nil, err
}
queryString := "SELECT client_id, location, current_load_in_amperes FROM power_usage"
q := client.NewQuery(queryString, DATABASE, "ns")
response, err := influxClient.Query(q)
if err != nil {
return nil, err
}
err = response.Error()
if err != nil {
return nil, errors.New("Empty record set")
} else {
res := response.Results
if (len(res) == 0) {
return nil, err
}
columns := response.Results[0].Series[0].Columns
points := response.Results[0].Series[0].Values
data := []map[string]interface{}{}
for i := 0; i <= len(points) - 1 ; i++ {
record := map[string]interface{}{}
for j := 0; j <= len(columns) - 1; j++ {
record[string(columns[j])] = points[i][j]
}
data = append(data, record)
}
resp := map[string]interface{}{"data" : data}
return resp, nil
}
}
Save and close the influxdb.go
file when you're through with editing.
In the above file, you have two functions. You're using the createPoint
function to connect and create a point in your InfluxDB database using the payload passed from the main.go
file. Then, you're using the getPoints()
function to connect and retrieve points from the power_usage
measurement. In each case, you're returning a map to the calling function or an error, if any.
4. Test the Golang InfluxDb Application.
You now have a main.go
file that listens for incoming requests and an influxdb.go
that creates and retrieves points from your InfluxDB database. Your application is now ready for testing.
Download the InfluxDB packages that you've used in the project.
$ go get github.com/influxdata/influxdb1-client/v2
Next, run the application. A web server should now listen on port 8080
. Don't enter any other command in this SSH
session.
$ go run ./
SSH to your server on another terminal window and execute the following curl
POST
command to create a new entry into your InfluxDB database.
$ curl -i -X POST localhost:8080/power-consumptions -H "Content-Type: application/json" -d '{"client_id": "656565", "location": "NAIROBI", "current_load_in_amperes": 0.3}'
Confirm the following output. This means you've successfully created a new point into the database.
{
"data": "Success"
}
Then, issue the following GET
command to retrieve points from the database.
$ curl -i -X GET localhost:8080/power-consumptions
You should get the following output with all points, including the latest NAIROBI
entry you've created with the curl
command.
{
"data": [
{
"client_id": "100731",
"current_load_in_amperes": 0.2,
"location": "BRANSON",
"time": 1638542140183389389
},
{
"client_id": "800478",
"current_load_in_amperes": 0.1,
"location": "MIAMI",
"time": 1638542147803130270
},
{
"client_id": "907854",
"current_load_in_amperes": 0.4,
"location": "CHICAGO",
"time": 1638542155163864457
},
{
"client_id": "532681",
"current_load_in_amperes": 0.1,
"location": "CHARLESTON",
"time": 1638542162283179983
},
{
"client_id": "656565",
"current_load_in_amperes": 0.3,
"location": "NAIROBI",
"time": 1638542346252178453
}
]
}
Your application is working as expected.
Conclusion
In this guide, you've implemented InfluxDB database functions with Golang on your Ubuntu 20.04 server to create and retrieve points using a custom JSON API.
Follow the links below to read more Golang tutorials:
Introduction
InfluxDB is an open-source time-series database specifically suitable for IoT projects, cloud-native services, and more. The package is written in the Golang programming language. You can use it for data exploration, data visualization, and to run dashboard applications.
While InfluxDB comes with great tools for storing, querying, and processing data, you can still use its API libraries inside your Golang project. This enhances flexibility when working with the time series data since you can pass it through custom functions that may not be available in the InfluxDB codebase.
In this guide, you'll implement the InfluxDB database functions with Golang on your Ubuntu 20.04 server.
Prerequisites
To proceed with this guide, make sure you have the following:
An Ubuntu 20.04 server.
A non-root sudo user.
An InfluxDB database server.
A Golang package.
1. Create an InfluxDB Database
In this tutorial, you'll set up an InfluxDB database and insert some time-series data for testing purposes. Later, you'll query your InfluxDB server via a Golang script to retrieve or insert points to the database.
Connect to your server to complete the following steps:
Log in to the InfluxDB server. Replace admin with the name of your InfluxDB super-user account. Pass the -password '' option to allow the following influx command to prompt you for a password.
$ influx -username 'admin' -password ''
Key in your password and press ENTER to proceed. Next, execute the following statement to create a sample_db database.
> CREATE DATABASE sample_db
Switch to the new sample_db database.
> USE sample_db
Insert the following points into your sample_db database under the power_usage measurement. In this application, you're tracking the power loads for users in different homes where a solar system has been installed. In this step, you'll enter the data manually, but this data may originate from IoT devices installed in all homes requiring measurement tracking in a production environment.
> INSERT power_usage,client_id=100731,location=BRANSON current_load_in_amperes=0.2
> INSERT power_usage,client_id=800478,location=MIAMI current_load_in_amperes=0.1
> INSERT power_usage,client_id=907854,location=CHICAGO current_load_in_amperes=0.4
> INSERT power_usage,client_id=532681,location=CHARLESTON current_load_in_amperes=0.1
Query the power_usage measurement to make sure the data is in place.
> SELECT "client_id", "location", "current_load_in_amperes" FROM power_usage
You should get the following output showing time-stamped data as you entered it in the sample_db database.
time client_id location current_load_in_amperes
---- --------- -------- -----------------------
1638542140183389389 100731 BRANSON 0.2
1638542147803130270 800478 MIAMI 0.1
1638542155163864457 907854 CHICAGO 0.4
1638542162283179983 532681 CHARLESTON 0.1
Log out from the InfluxDB server.
> QUIT
2. Create a main.go File
In this application, you'll create a main.go file. This runs the main(...) function that fires when you start the application.
Separate your source code files from the rest of the Linux files by creating a new project directory.
$ mkdir project
Next, navigate to the project directory.
$ cd project
Then, use nano to open a new main.go file.
$ nano main.go
Enter the following information into the main.go file.
package main
import (
"net/http"
"encoding/json"
"fmt"
)
func main() {
http.HandleFunc("/power-consumptions", httpHandler)
http.ListenAndServe(":8080", nil)
}
func httpHandler(w http.ResponseWriter, req *http.Request) {
var err error
resp := map[string]interface{}{}
if req.Method == "POST" {
params := map[string]interface{}{}
err = json.NewDecoder(req.Body).Decode(¶ms)
if err != nil {
fmt.Fprintf(w, err.Error())
}
resp, err = createPoint(params)
}
if req.Method == "GET" {
resp, err = getPoints()
}
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
if err != nil {
fmt.Println(err.Error())
} else {
if err := enc.Encode(resp); err != nil {
fmt.Println(err.Error())
}
}
}
Save and close the main.go file when you're through with editing.
In the above file, you've created a main() function to listen for incoming HTTP requests on port 8080. You've then redirected the request to the httpHandler() function to determine the HTTP req.Method. For POST requests, you're calling a createPoint(params) function, which you'll create in a new file later. This function accepts the JSON payload as an argument for the point that you want to create to the database.
Next, you're redirecting GET requests to the getPoints() function, which retrieves data from the database and returns a map.
3. Create an influxdb.go File
You'll create a file to interact with your InfluxDB server in this step. This file contains two functions. You'll use the createPoint() function to enter new points into the database and the getPoints() function to retrieve entries from your power_usage measurement.
Use nano to create a new influxdb.go file.
$ nano influxdb.go
Next, enter the following information into the influxdb.go file. Replace const USERNAME and const PASSWORD with the correct authentication credentials for your InfluxDB server.
package main
import (
"github.com/influxdata/influxdb1-client/v2"
"time"
"errors"
)
const (
USERNAME string = "admin"
PASSWORD string = "EXAMPLE_PASSWORD"
DATABASE string = "sample_db"
)
func createPoint(params map[string]interface{}) (map[string]interface{}, error) {
influxClient, err := client.NewHTTPClient(client.HTTPConfig{
Addr: "http://localhost:8086",
Username: USERNAME,
Password: PASSWORD,
})
if err != nil {
return nil, err
}
bp, err := client.NewBatchPoints(client.BatchPointsConfig{
Database: DATABASE,
})
if err != nil {
return nil, err
}
clientId := params["client_id"].(string)
location := params["location"].(string)
currentLoadInAmperes := params["current_load_in_amperes"]
pt, err := client.NewPoint("power_usage", map[string]string{"client_id": clientId, "location": location},
map[string]interface{}{"current_load_in_amperes": currentLoadInAmperes},
time.Now())
if err != nil {
return nil, err
}
bp.AddPoint(pt)
err = influxClient.Write(bp)
if err != nil {
return nil, err
}
resp := map[string]interface{}{"data" : "Success"}
return resp, nil
}
func getPoints() (map[string]interface{}, error) {
influxClient, err := client.NewHTTPClient(client.HTTPConfig{
Addr: "http://localhost:8086",
Username: USERNAME,
Password: PASSWORD,
})
if err != nil {
return nil, err
}
queryString := "SELECT client_id, location, current_load_in_amperes FROM power_usage"
q := client.NewQuery(queryString, DATABASE, "ns")
response, err := influxClient.Query(q)
if err != nil {
return nil, err
}
err = response.Error()
if err != nil {
return nil, errors.New("Empty record set")
} else {
res := response.Results
if (len(res) == 0) {
return nil, err
}
columns := response.Results[0].Series[0].Columns
points := response.Results[0].Series[0].Values
data := []map[string]interface{}{}
for i := 0; i <= len(points) - 1 ; i++ {
record := map[string]interface{}{}
for j := 0; j <= len(columns) - 1; j++ {
record[string(columns[j])] = points[i][j]
}
data = append(data, record)
}
resp := map[string]interface{}{"data" : data}
return resp, nil
}
}
Save and close the influxdb.go file when you're through with editing.
In the above file, you have two functions. You're using the createPoint function to connect and create a point in your InfluxDB database using the payload passed from the main.go file. Then, you're using the getPoints() function to connect and retrieve points from the power_usage measurement. In each case, you're returning a map to the calling function or an error, if any.
4. Test the Golang InfluxDb Application.
You now have a main.go file that listens for incoming requests and an influxdb.go that creates and retrieves points from your InfluxDB database. Your application is now ready for testing.
Download the InfluxDB packages that you've used in the project.
$ go get github.com/influxdata/influxdb1-client/v2
Next, run the application. A web server should now listen on port 8080. Don't enter any other command in this SSH session.
$ go run ./
SSH to your server on another terminal window and execute the following curl POST command to create a new entry into your InfluxDB database.
$ curl -i -X POST localhost:8080/power-consumptions -H "Content-Type: application/json" -d '{"client_id": "656565", "location": "NAIROBI", "current_load_in_amperes": 0.3}'
Confirm the following output. This means you've successfully created a new point into the database.
{
"data": "Success"
}
Then, issue the following GET command to retrieve points from the database.
$ curl -i -X GET localhost:8080/power-consumptions
You should get the following output with all points, including the latest NAIROBI entry you've created with the curl command.
{
"data": [
{
"client_id": "100731",
"current_load_in_amperes": 0.2,
"location": "BRANSON",
"time": 1638542140183389389
},
{
"client_id": "800478",
"current_load_in_amperes": 0.1,
"location": "MIAMI",
"time": 1638542147803130270
},
{
"client_id": "907854",
"current_load_in_amperes": 0.4,
"location": "CHICAGO",
"time": 1638542155163864457
},
{
"client_id": "532681",
"current_load_in_amperes": 0.1,
"location": "CHARLESTON",
"time": 1638542162283179983
},
{
"client_id": "656565",
"current_load_in_amperes": 0.3,
"location": "NAIROBI",
"time": 1638542346252178453
}
]
}
Your application is working as expected.
Conclusion
In this guide, you've implemented InfluxDB database functions with Golang on your Ubuntu 20.04 server to create and retrieve points using a custom JSON API.
Follow the links below to read more Golang tutorials:
Designing a Modern API with Golang and MySQL 8 on Linux
Secure a Golang Web Server with a Self-signed or Let's Encrypt SSL Certificate
How to Create a Central Input Data Validator in Golang