Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Golang Mongo driver and Openshift
Austin Cunningham
Austin Cunningham

Posted on • Edited on

     

Golang Mongo driver and Openshift

I wanted to learn how to create a rest Api with Golang and MongoDb, found a lot of tutorials using themgo library but as this was unmaintained. I used theMongo driver instead withgorilla/mux. First set up package and imports.

packagemainimport("fmt""log""net/http""context""encoding/json""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options""go.mongodb.org/mongo-driver/bson""go.mongodb.org/mongo-driver/bson/primitive""github.com/gorilla/mux""github.com/austincunningham/GolangUserRestApi/models")
Enter fullscreen modeExit fullscreen mode

Setup the routes and Mongo db connection

// setting a global DB struct to be accessible to route functionstypeDBstruct{collection*mongo.Collection}// Define the routesfuncmain(){fmt.Printf("REST API User from golang\n")// Set client optionsclientOptions:=options.Client().ApplyURI("mongodb://localhost:27017")// Connect to MongoDBclient,err:=mongo.Connect(context.TODO(),clientOptions)iferr!=nil{log.Fatal(err)}// Check the connectionerr=client.Ping(context.TODO(),nil)iferr!=nil{log.Fatal(err)}deferclient.Disconnect(context.TODO())collection:=client.Database("golang-user").Collection("users")db:=&DB{collection:collection}fmt.Println("Connected to MongoDB!")//outputsfmt.Printf("Server listing on http://localhost:8080/users")fmt.Printf("\nCTRL C to exit\n")// Controller for endpointsr:=mux.NewRouter()r.HandleFunc("/users",db.AllUsers).Methods("GET")r.HandleFunc("/users/{id}",db.FindUser).Methods("GET")r.HandleFunc("/users",db.CreateUser).Methods("POST")r.HandleFunc("/users/{id}",db.UpdateUser).Methods("PUT")r.HandleFunc("/users/{id}",db.DeleteUser).Methods("DELETE")iferr:=http.ListenAndServe(":8080",r);err!=nil{log.Fatal(err)}}
Enter fullscreen modeExit fullscreen mode

Setup the model package

packagemodelsimport("go.mongodb.org/mongo-driver/bson/primitive")// the properties in Mongodb documenttypeUserstruct{Idprimitive.ObjectID`json:"_id,omitempty" bson:"_id,omitempty"`Namestring`bson:"name" json:"name"`Emailstring`bson:"email" json:"email"`Passwordstring`bson:"password" json:"password"`}
Enter fullscreen modeExit fullscreen mode

Back in the main package define the
GET all users function

// find all usersfunc(db*DB)AllUsers(reshttp.ResponseWriter,req*http.Request){fmt.Println("AllUsers GET")// create an array of usersvarresults[]models.Uservarusermodels.User// set the api headerres.Header().Set("content-type","application/json")// set the find options, not sure I need thisfindOptions:=options.Find()// use the find command to get allresult,err:=db.collection.Find(context.TODO(),bson.D{{}},findOptions)iferr!=nil{fmt.Println("AllUsers GET failed to query DB",err)}//go through the result and decode each element at a timeforresult.Next(context.TODO()){err:=result.Decode(&user)iferr!=nil{log.Fatal(err)}// add to the arrayresults=append(results,user)}//return the array as jsonjson.NewEncoder(res).Encode(results)}
Enter fullscreen modeExit fullscreen mode

GET find user by id function

// find a single userfunc(db*DB)FindUser(reshttp.ResponseWriter,req*http.Request){fmt.Println("FindUser GET")varusermodels.Userparams:=mux.Vars(req)objectId,_:=primitive.ObjectIDFromHex(params["id"])res.Header().Set("content-type","application/json")filter:=bson.M{"_id":objectId}err:=db.collection.FindOne(context.TODO(),filter).Decode(&user)iferr!=nil{fmt.Println("error",err)}json.NewEncoder(res).Encode(user)}
Enter fullscreen modeExit fullscreen mode

DELETE user by id is pretty similar

func(db*DB)DeleteUser(reshttp.ResponseWriter,req*http.Request){fmt.Println("DeleteUser DELETE")params:=mux.Vars(req)objectId,_:=primitive.ObjectIDFromHex(params["id"])res.Header().Set("content-type","application/json")filter:=bson.M{"_id":objectId}result,err:=db.collection.DeleteOne(context.TODO(),filter)iferr!=nil{fmt.Println("DeleteUser DELETE failed to query DB",err)}json.NewEncoder(res).Encode(result)}
Enter fullscreen modeExit fullscreen mode

PUT update user by id

func(db*DB)UpdateUser(reshttp.ResponseWriter,req*http.Request){fmt.Println("UpdateUser PUT")varusermodels.User// get the id from the urlparams:=mux.Vars(req)objectId,_:=primitive.ObjectIDFromHex(params["id"])// set the header infores.Header().Set("content-type","application/json")//set the filter on the idfilter:=bson.M{"_id":objectId}// decode the request body_=json.NewDecoder(req.Body).Decode(&user)update:=bson.M{"$set":&user}result,err:=db.collection.UpdateOne(context.TODO(),filter,update)iferr!=nil{fmt.Println("UpdateOne PUT failed to query DB ",err)}json.NewEncoder(res).Encode(result)}
Enter fullscreen modeExit fullscreen mode

POST create user

func(db*DB)CreateUser(reshttp.ResponseWriter,req*http.Request){fmt.Println("CreateUser POST")varusermodels.Userres.Header().Set("content-type","application/json")_=json.NewDecoder(req.Body).Decode(&user)result,err:=db.collection.InsertOne(context.TODO(),user)iferr!=nil{fmt.Println("CreateUser Error inserting record ",err)}json.NewEncoder(res).Encode(result)}
Enter fullscreen modeExit fullscreen mode

So the rest api is all setup at this point to connect to my local MongoDb.

Setup the container and deploy to Openshift

First I set up a project in Openshift 3.11, onMinishift

oc new-project golanguser
Enter fullscreen modeExit fullscreen mode

Login to the Openshift console and deploy Mongodb from the Openshift catalog. Open the project in the console and click onBrowse Catalog
Alt Text
Click on Mongodb
Alt Text
Follow the creation flow until you get toConfiguration set the following as some will be auto generated if you don't

  • Database Service Name
  • MongoDB Connection Username
  • MongoDB Connection Password
  • MongoDB Database Name
  • MongoDB Admin Password

Once set click the create button
Alt Text
The Results screen will have the connection url. I will be using part of the connection url in the code.
Alt Text

Change the connection url in the main package here

// Set client optionsclientOptions:=options.Client().ApplyURI("mongodb://myadmin:password@mongodb:27017")
Enter fullscreen modeExit fullscreen mode

And make sure that your collection is pointing at the correct db

collection:=client.Database("golanguser").Collection("users")
Enter fullscreen modeExit fullscreen mode

Once these are set we are ready to create the golang container with the followingdockerfile

# Start from the latest golang base imageFROM golang:latest# Set the Current Working Directory inside the containerWORKDIR /app# Copy go mod and sum filesCOPY go.mod go.sum ./# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changedRUN go mod download# Copy the source from the current directory to the Working Directory inside the containerCOPY..# Build the Go appRUN go build-o main.# Expose port 8080 to the outside worldEXPOSE 8080# Command to run the executableCMD["./main"]
Enter fullscreen modeExit fullscreen mode

Build the image and push it to a remote registry

docker build-t austincunningham/golanguserrestapi:latest.docker push austincunningham/golanguserrestapi:latest
Enter fullscreen modeExit fullscreen mode

You can then add the Image to project in the Openshift consoleAdd to Project/Deploy Image

Alt Text

Enter the Image Name click the search icon and deploy when the image is found

Alt Text

Once the container is deployed you can test the connection between MongoDb and the rest api as follows

oc project golanguseroc get podsNAME                        READY     STATUS    RESTARTS   AGEgolanguserrestapi-1-7px9p   1/1       Running   1          14hmongodb-1-s9fkd             1/1       Running   6          8d# log into the podocexec-it golanguserrestapi-1-7px9p bash# curl and POST some datacurl--header"Content-Type: application/json"--request POST--data'{"name":"austin","email":"austin@austin.com","password":"password"}' http://localhost:8080/users# successful response{"InsertedID":"5ef7a5dba99a0cb3de9302dc"}# curl the GET all endpointcurl http://localhost:8080/users[{"_id":"5ef7a5dba99a0cb3de9302dc","name":"austin","email":"austin@austin.com","password":"password"}]
Enter fullscreen modeExit fullscreen mode

Final step is to add a route click on the rest container andcreate route
Alt Text

Except the defaults your route will appear in the console it can be accessed from any where with the users route

Alt Text

Code liveson github and the container imageon dockerhub

Top comments(1)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
pmgysel profile image
Philipp Gysel
I love Java☕. 6 years of professional experience. I am interested in architecture, SpringBoot, and new Java features.
  • Email
  • Location
    Switzerland
  • Education
    Master's degree in ECE
  • Work
    Software Engineer at Intersys AG
  • Joined

wow great stuff, thanks Austin! Always great to have a working example 😀

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

nuff said
  • Location
    Waterford, Ireland
  • Work
    Senior Software Engineer at Red Hat
  • Joined

More fromAustin Cunningham

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp