Thursday, September 24, 2015

Deploying Go on Google App Engine

Why GAE?

For the uninitiated, Google App Engine (GAE) is a PaaS (Platform as a Service). By deploying your app here, you get the following 2 immediate benefits:
      1. No servers for you to maintain.
      2. Easy to scale as your traffic & data storage needs change.
GAE is now a part of Google Cloud Platform. 

Google Cloud Platform is a set of modular cloud-based services that allow you to create anything from simple websites to complex applications.

Google Cloud Platform is build on the same infrastructure that allows Google to return billions of search results in milliseconds, serve 6 billion hours of YouTube video per month and provide storage for 425 million Gmail users!

Do You Want to See the Live Page that I Deployed on GAE?


Visit http://golangprogae.appspot.com/. This is a responsive page build on Bootstrap framework.


Getting Started with Go on GAE

Download and unzip the Go App Engine SDK

P.S. - Add App Engine Go SDK directory to your PATH environment. Also, Go requires Python 2.7x, Download it from here, if it's not already installed in your machine.
  1. Go to your working directory. Create a new project directory and name it anything you may like, I've named it gogae. 
  2. Inside this project directory, create a file named app.yaml
  3. Copy the following code and paste it to your app.yaml file. Remember, later on you've to edit the application name marked in red (golangprogaewith your own Project Id that you'll create in GAE interface at the end of this tutorial.
Info. - app.yaml contains GAE application configuration. In the above RefCode# 1, you can change the version. GAE has the ability to render different versions based on your preference, if you wish to go for A/B testing.

RefCode# 1


# This is a comment
# application is mandatory (replace with your project Id)
application: golangprogae
# version is mandatory
version: 1
# runtime is mandatory
runtime: go
# api_version is mandatory
api_version: go1
# handlers is mandatory
handlers: 
- url: /.*
  script: _go_app

4. Create another file, name it whatever you like. I've named it as bootstrap.go

RefCode# 2


package gocloud

import (
 "fmt"
 "net/http"
 
)

func init() {
 http.HandleFunc("/", handler)
 
}

func handler(writer http.ResponseWriter, request *http.Request) {
 
 fmt.Fprint(writer, "<!DOCTYPE html><html><head><title>Go web app on GAE</title><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><link rel='stylesheet' href='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'><script src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js'></script><script src='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js'></script></head><body><div class='container'><div class='jumbotron'><h1>Go App on GAE</h1><p>Resize this responsive page to see the effect of Bootstrap! For details <a href='http://www.golangpro.com'>visit GolangPro</a></p> </div><div class='row'><div class='col-sm-4'><h3>Why Go?</h3><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p><p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p></div><div class='col-sm-4'><h3>Why GAE?</h3><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p><p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p></div><div class='col-sm-4'><h3>Why Bootstrap?</h3><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p><p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p></div></div></div></body></html>" )
 
}

Deploy to your Local Machine [Development Server]

I'm using a windows machine.


In command prompt navigate to the project directory (gogae) that you created a little while ago in the beginning of this tutorial. Once you're inside the project directory use the following command to deploy it locally:

goapp serve

Once you successfully execute the above command open the following to see the result:

http://localhost:8080/

The Development Server will display the web page that we just build using Go.

If you wish you can check the local Admin Server of GAE running for this app on your local machine. Open the following:

http://localhost:8000/

It looks like the following image:




How to Deploy to Google App Engine?

1. Log into Google Developer Console

For those who are yet to signup, at the time of writing this there's a $ 300 credit promo for FREE to try out Google Cloud Platform.

2.  Create a new project. Note down the Project Id. In my case the project Id is golangprogae


3. Open the file named app.yaml. You've to edit the project Id before deployment, see RefCode# 1 above (in the beginning of this article). Edit the name of the application marked in red and replace with your Project Id.

4. In command prompt navigate to the project directory (gogae) that you created a while ago. Once inside the project folder use the following command to deploy it to GAE:

goapp deploy


5. It hardly takes 5 seconds for this app to get deployed. Once it is completed visit <http://YOUR_PROJECT_ID.appspot.com>. In my case it's http://golangprogae.appspot.com/

How was it? How can I improve this? Please share your thoughts.

Friday, September 4, 2015

Embedded or Anonymous Fields in Structs

For an introduction to Structs read: Go Structs   


Go supports anonymous or embedded field - i.e. a field without a name but with a type. You can say that the type itself is a name.

Why Anonymous or Embedded Fields or Composition?


Yes, Embedded fields, Composition or Anonymous fields are different names for same concept.

If you're familiar with object oriented programming you can relate an anonymous or embedded field with Inheritance and its single biggest advantage is code re-usability. 

CodeRef# 1


package main

import "fmt"

type person struct {
 name   string
 gender string
 age    int
}

type employee struct {
 person //embedded field
 salary float64
 dept   string
}

func main() {
 empProfile := employee{person{"Jack", "M", 32}, 3000, "Electronics"}
 fmt.Println(empProfile)
 fmt.Printf("%s works in %s department. Salary: %.2f\n", empProfile.name, empProfile.dept, empProfile.salary)
}

Output

{{Jack M 32} 3000 Electronics}
Jack works in Electronics department. Salary: 3000.00

Play with the above code

CodeRef# 2


package main

import "fmt"

type person struct {
 name   string
 gender string
 age    int
}

type employee struct {
 person //embedded field
 salary float64
 dept   string
}

type manager struct {
 employee //embedded field
 numEmp int
}

func main() {
 empProfile := employee{person{"Jack", "M", 32}, 3000, "Electronics"}
 mgr := manager{employee{person{"Bill", "M", 55}, 5000, "CSc"},21}
 fmt.Printf("%s works in %s department. Salary: %.2f\n", empProfile.name, empProfile.dept, empProfile.salary)
 fmt.Printf("%s manages %s department with %d employees. Salary: %.2f", mgr.name, mgr.dept, mgr.numEmp, mgr.salary,)
}

Output
Jack works in Electronics department. Salary: 3000.00
Bill manages CSc department with 21 employees. Salary: 5000.00
Play with the code here
What Happens in Case of a Field with the Same Name in Two Structs?
For example see the following: 
A field named location exists in both the structs (person and employee). 
  • What happens when you call empProfile.location? 
  • Which location gets a precedence?
RefCode# 3
package main
import "fmt"

type person struct {
 name, gender, location  string
}

type employee struct {
 person //embedded field
 salary float64
 dept   string
 location string
}

func main() {
 empProfile := employee{person{"Jack", "M", "Chicago"}, 3000, "M", "New York"}
 fmt.Printf("%s. Current location: %s\n", empProfile.name, empProfile.location)
 fmt.Printf("%s. Native location: %s\n", empProfile.name, empProfile.person.location)
}

Jack. Current location: New York
Jack. Native location: Chicago
Play with the code here
As it is evident from the above output, the child field (i.e. the location from employee) takes precedence over the parent (i.e. person). In Object Oriented parlance this provides a way to override a field or method.
If you liked it, spread the word about it. Happy coding!