DEV Community

Parth Shukla
Parth Shukla

Posted on

Rest API with Golang and Cassandra DB

Apache Cassandra is a highly scalable, high-performance distributed database designed to handle large amounts of data across many commodity servers, providing high availability with no single point of failure. It is a type of NoSQL database.

In this post we'll be creating a REST API form Golang and Cassandra DB.

Firsly I'll outline of this blog.

  1. Create a keyspace of Cassandra (Similar to Database in MySQL)

  2. Create a table inside the keyspace

  3. Connect with go-cql connector

  4. Create the rest-api

NOTE: This blog is being written according to an ubuntu system so there may be some minute changes according to your OS.

1. Create a keyspace of Cassandra

CREATE KEYSPACE users
WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 1};
Enter fullscreen mode Exit fullscreen mode

A replication factor of one means that there is only one copy of each row in the Cassandra cluster. A replication factor of two means there are two copies of each row, where each copy is on a different node.

The details of these terms are not the focus of this blog thus I will explain in it in some later blogs.

2. Create a table inside the keyspace

use users;

CREATE TABLE stu(
   username text PRIMARY KEY,
   email text
   );
Enter fullscreen mode Exit fullscreen mode

TIME FOR SOME GOLANG !!!

Firstly we'll create a main.go file and inside it we'll create a struct to map with the database structure

type Student struct {
    Username string `json:"username"`
    Email    string `json:"email"`
}

Enter fullscreen mode Exit fullscreen mode

For connecting with the cassandra we'll use gocql package and link of it is given below.

github.com/gocql/gocql

Now we will create our main function and start the server

func main() {
    http.HandleFunc("/", handleRequest)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
    fmt.Println("Server has Started")

}
Enter fullscreen mode Exit fullscreen mode

For our cassandra client we'll create a new struct named Client which will have a pointer to gocql.Session which has all the required functionalities to interact with the database.

type Client struct {
    cassandra *gocql.Session
}

var cassandraClient *Client

Enter fullscreen mode Exit fullscreen mode

The IniitalizeDB() function

This function is responsible for creating a connection between cassandra and Go and returning a *Client type variable

func InitializeDB() *Client {
    cluster := gocql.NewCluster("127.0.0.1")
    cluster.Consistency = gocql.Quorum
    cluster.Keyspace = "users"
    session, _ := cluster.CreateSession()
    fmt.Println("********************** Cassandra Initialized")
    return &Client{cassandra: session}
}
Enter fullscreen mode Exit fullscreen mode

Now we call the InitializeDb() in the main function and pass the cassandraClient in a variable.

cassandraClient = InitializeDB();
Enter fullscreen mode Exit fullscreen mode

Now we map the request to functions according to the POST, GET, PUT, DELETE

func handleRequest(w http.ResponseWriter, r *http.Request) {
    switch true {
    case r.Method == "POST":
        createStudent(w, r)
    case r.Method == "GET":
        getStudent(w, r)
    case r.Method == "PUT":
        updateStudent(w, r)
    case r.Method == "DELETE":
        deleteStudent(w, r)
    }

}
Enter fullscreen mode Exit fullscreen mode

Atlast all the setup is done now we create the CRUD operations:

1. CreateStudent function

We have 2 functions firstly createStudent function which takes in the post request and routes it CreateStudent function which does the database query.

to Insert into cassandra we use the query.

INSERT INTO users (username, email) VALUES(?,?) and then add in the values.

the functions are below.

func createStudent(w http.ResponseWriter, r *http.Request) {
    var NewUser Student
    reqBody, err := ioutil.ReadAll(r.Body)
    if err != nil {
        fmt.Fprintf(w, "wrong data")
    }
    json.Unmarshal(reqBody, &NewUser)
    //Call the DB
    err = cassandraClient.CreateStudent(NewUser)
    if err != nil {
        panic(err)
    }
    fmt.Println(NewUser)

}



func (s *Client) CreateStudent(stu Student) error {
    err := s.cassandra.Query("INSERT INTO users (username, email) VALUES(?,?)", stu.Username, stu.Email).Exec()
    if err != nil {
        return err
    }

    return nil
}

Enter fullscreen mode Exit fullscreen mode

Similarly for the other methods

2. Update Student

UPDATE users SET email=? WHERE username=?


func updateStudent(w http.ResponseWriter, r *http.Request) {
    var UpdateStu Student
    reqBody, err := ioutil.ReadAll(r.Body)
    if err != nil {
        fmt.Fprintf(w, "Kindly enter data properly")
    }
    json.Unmarshal(reqBody, &UpdateStu)
    //DB Call
    err = cassandraClient.UpdateStudent(UpdateStu)
    if err != nil {
        panic(err)
    }
    fmt.Println(UpdateStu)

}



func (s *Client) UpdateStudent(stu Student) error {
    err := s.cassandra.Query("UPDATE users SET email=? WHERE username=?", stu.Email, stu.Username).Exec()
    if err != nil {
        return err
    }
    return nil
}


Enter fullscreen mode Exit fullscreen mode

3. Get Student

SELECT * FROM users WHERE username=?

func getStudent(w http.ResponseWriter, r *http.Request) {
    name := r.URL.Query().Get("username")
    //DB call
    stu, err := cassandraClient.GetStudent(name)
    if err != nil {
        panic(err)
    }
    fmt.Println(stu)
}

func (s *Client) GetStudent(username string) (Student, error) {

    stu := Student{}
    ctx := context.Background()
    err := s.cassandra.Query("SELECT * FROM users WHERE username=?", username).WithContext(ctx).Consistency(gocql.One).Scan(&stu.Username, &stu.Email)
    if err != nil {
        return stu, err
    }
    return stu, nil
}


Enter fullscreen mode Exit fullscreen mode

4. Delete Student

func deleteStudent(w http.ResponseWriter, r *http.Request) {
    name := r.URL.Query().Get("username")
    //Db Call
    err := cassandraClient.DeleteStudent(name)
    if err != nil {
        panic(err)
    }
    fmt.Println("Successfully Deleted")

}


func (s *Client) DeleteStudent(name string) error {
    err := s.cassandra.Query("DELETE FROM users WHERE username=?", name).Exec()
    if err != nil {
        return err
    }
    return nil
}


Enter fullscreen mode Exit fullscreen mode

So now if you want to access the whole code here is the link
https://github.com/mrshukla1805/golang-cassandra

Please do provide a star on the repository!!

Enjoy and keep learning ;)

Top comments (0)