Go

Golang is a programming language initially developed at Google in year 2007 by Robert Griesemer, Rob Pike, and Ken Thompson. Go programming language is a statically-typed language with syntax similar to that of C. It provides garbage collection, type safety, dynamic-typing capability, many advanced built-in types such as variable length arrays and key-value maps. It also provides a rich standard library.

 

MongoDB

MongoDB is a free and open-source cross-platform document-oriented database program. Classified as a NoSQLdatabase program, MongoDB uses JSON-like documents with schemas.

 

RESTAPI

One of the most popular types of API is REST or, as they’re sometimes known, RESTful APIs. REST or RESTful APIs were designed to take advantage of existing protocols. While REST – or Representational State Transfer – can be used over nearly any protocol, when used for web APIs it typically takes advantage of HTTP. This means that developers have no need to install additional software or libraries when creating a REST API

 

Installation of  MongoDB Server:

Import they GPG key for the official MongoDB repository.

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

Add the MongoDB repository details so APT

$ echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list

After adding the repository details, we need to update the packages list.

$ sudo apt-get update

Install MongoDB

$ sudo apt-get install -y mongodb-org

 

 

Installation of  Go:

Download the latest package for Go by running this command, which will pull down the Go package file, and save it to your current working directory.

$ sudo curl -O https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz

Now we can set the Go paths

$ sudo vi ~/.profile

At the end of the file, add this line:

export GOROOT=$HOME/go
export PATH=$PATH:$GOROOT/bin

With the appropriate line pasted into your profile, save and close the file. Next, refresh your profile by running:

$ source ~/.profile

 

 

Build RESTful API in Go and MongoDB

 

The REST API service will create endpoints to manage a store of movies. The operations that our endpoints will allow are:

GET       /movies               Get list of movies

GET       /movies/:id         Find a movie by it’s id

POST    /movies                Create a new movie

Before we begin, we need to get the packages to setup the API:

  • toml :  Parse the configuration file (MongoDB server & credentials)
  • mux : Request router and dispatcher for matching incoming requests to their respective handler
  • mgo : MongoDB driver
$ go get github.com/BurntSushi/toml gopkg.in/mgo.v2 github.com/gorilla/mux

After  installing the dependencies, we create a file called “app.go“, with the following content:

package main
import (import ( "fmt" "log" "net/http"
 "github.com/gorilla/mux")
func AllMoviesEndPoint(w http.ResponseWriter, r *http.Request) {func AllMoviesEndPoint(w http.ResponseWriter, r *http.Request) { movies, err := dao.FindAll() if err != nil { respondWithError(w, http.StatusInternalServerError, err.Error()) return } respondWithJson(w, http.StatusOK, movies)}
func FindMovieEndpoint(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) movie, err := dao.FindById(params["id"]) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid Movie ID") return respondWithJson(w, http.StatusOK, movie)}
func CreateMovieEndPoint(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() var movie Movie if err := json.NewDecoder(r.Body).Decode(&movie); err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload") return } movie.ID = bson.NewObjectId() if err := dao.Insert(movie); err != nil { respondWithError(w, http.StatusInternalServerError, err.Error()) return } respondWithJson(w, http.StatusCreated, movie)
func UpdateMovieEndPoint(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() var movie Movie if err := json.NewDecoder(r.Body).Decode(&movie); err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload") return } if err := dao.Update(movie); err != nil { respondWithError(w, http.StatusInternalServerError, err.Error()) returnrespondWithJson(w, http.StatusOK, map[string]string{"result": "success"})}func DeleteMovieEndPoint(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() var movie Movie if err := json.NewDecoder(r.Body).Decode(&movie); err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload") return } if err := dao.Delete(movie); err != nil { respondWithError(w, http.StatusInternalServerError, err.Error()) return } respondWithJson(w, http.StatusOK, map[string]string{"result": "success"})}func main() { r := mux.NewRouter() r.HandleFunc("/movies", AllMoviesEndPoint).Methods("GET") r.HandleFunc("/movies", CreateMovieEndPoint).Methods("POST") r.HandleFunc("/movies", UpdateMovieEndPoint).Methods("PUT") r.HandleFunc("/movies", DeleteMovieEndPoint).Methods("DELETE") r.HandleFunc("/movies/{id}", FindMovieEndpoint).Methods("GET") if err := http.ListenAndServe(":3000", r); err != nil { log.Fatal(err) }}

The above code will create a controller for each endpoint, then make an HTTP server on port 3000.

Now create a basic Moviemodel. In Go, we use struct keyword to create a model:

type Movie struct { 
    ID          bson.ObjectId `bson:"_id" json:"id"` 
    Name        string        `bson:"name" json:"name"` 
    CoverImage  string        `bson:"cover_image" json:"cover_image"` 
    Description string        `bson:"description" json:"description"`}

Create the Data Access Object to manage database operations.

package dao
import (
  "log"
"github.com/mlabouardy/movies-restapi/models"
 mgo "gopkg.in/mgo.v2" 
 mgo "gopkg.in/mgo.v2" 
"gopkg.in/mgo.v2/bson"
)
type MoviesDAO struct { 
Server   string 
Database string
}
var db *mgo.Database
const ( 
COLLECTION = "movies"
)
func (m *MoviesDAO) Connect() { 
session, err := mgo.Dial(m.Server) 
if err != nil { 
log.Fatal(err) } 
db = session.DB(m.Database)
}
ffunc (m *MoviesDAO) FindAll() ([]Movie, error) { 
var movies []Movie 
err := db.C(COLLECTION).Find(bson.M{}).All(&movies) 
return movies, err
}
func (m *MoviesDAO) FindById(id string) (Movie, error) { 
var movie Movie 
err := db.C(COLLECTION).FindId(bson.ObjectIdHex(id)).One(&movie) 
return movie, err
}
func (m *MoviesDAO) Insert(movie Movie) error { 
err := db.C(COLLECTION).Insert(&movie) 
return err
}
func (m *MoviesDAO) Delete(movie Movie) error { 
err := db.C(COLLECTION).Remove(&movie) 
return err
}
func (m *MoviesDAO) Update(movie Movie) error { 
err := db.C(COLLECTION).UpdateId(movie.ID, &movie) 
return err
}

To run the server in local, type the following command:

$ go run app.go

Create a Movie

api 1

 List of Movies

 api 2

Advertisements