Introduction
Last time, we covered how to get a very simple hello world application running in Bluemix. This application required only Go's standard library. It was stateless because it didn't need to store any data or perform any kind of synchronization. There were no support files such as html or javascript. Also, it did not need to connect to any other services such as email.
This article attempts to fill in these gaps so that you can create more realistic Bluemix applications.
Third-Party Libraries
Sometimes, the Go standard library doesn't have everything you need. For instance, third-party libraries are often the only way to connect to a database. When you deploy your Bluemix application with the Go buildpack, it runs in "offline" mode. This means that it can't simply "go get" the libraries that you need. Instead, you must use the godep tool so that your application and all of its dependencies are uploaded directly from your laptop to Bluemix.
To install godep run "go get github.com/tools/godep." Change directory into your project and run "godep save." Godep requires an scm system in order to run the save operation. If you have not yet set up Git or you use an scm that it doesn't recognize you will need to run "git init" in your project before the save operation.
The next time you run "cf push" it should deploy your application along with its dependencies so that it compiles.
Setting Up MySQL
Data stored in memory is wiped every time your application restarts. Also, if you want to use multiple application instances they do not share the memory. You run into similar problems if you attempt to use the local filesystem. The solution is to use a database to store your application data.
Bluemix offers two different MySQL database systems at the time this article was written: MySQL and ClearDB. Both services provide an MySQL database instance and communicate the credentials to your applications via the VCAP_SERVICES environment variable. This is actually one of the best practices of a Twelve Factor Application, which says to decouple your services as much as possible using environment variables to bind them together.
Try creating one of these services using the Bluemix dashboard. When it prompts you for the application to bind, pick your Go application. The service is initialized and your application is restarted. Once it has restarted you can click on your Go application in the dashboard and see the services that are bound to it. Click on the "Show Credentials" link on the service and you will see a flyout with the JSON snippet that is in the environment variable for your application. You can see that the host, port, username and password are provided, which should be sufficient to establish a database connection in your application.
There are two popular MySQL drivers available for Go: MyMySQL and Go-MySQL-Driver. Learning how to use MySQL and the drivers is beyond the scope of this article. Pick the one that satisfies your requirements and install it using the "go get" tool (e.g. "go get github.com/ziutek/mymysql"). Add the necessary imports to your Go files. Run "godep save" to add the driver code to the godep repository in your project.
As mentioned earlier, all of the necessary connection information for MySQL can be found in the VCAP_SERVICES environment variable. Notice that when you checked your dashboard for the credentials they showed up in a json format. You need to parse out the particular information you need for MySQL using the json parser. Check out the following code snippet to see how I extracted the information from the ClearDB service. If you chose the MySQL service you will find that you can parse the details in a very similar way.
Now that you have the service and driver set up you can begin writing your code to populate and query your MySQL database. When you have finished writing your code you can deploy it by running "cf push" command.
Bluemix offers two different MySQL database systems at the time this article was written: MySQL and ClearDB. Both services provide an MySQL database instance and communicate the credentials to your applications via the VCAP_SERVICES environment variable. This is actually one of the best practices of a Twelve Factor Application, which says to decouple your services as much as possible using environment variables to bind them together.
Try creating one of these services using the Bluemix dashboard. When it prompts you for the application to bind, pick your Go application. The service is initialized and your application is restarted. Once it has restarted you can click on your Go application in the dashboard and see the services that are bound to it. Click on the "Show Credentials" link on the service and you will see a flyout with the JSON snippet that is in the environment variable for your application. You can see that the host, port, username and password are provided, which should be sufficient to establish a database connection in your application.
There are two popular MySQL drivers available for Go: MyMySQL and Go-MySQL-Driver. Learning how to use MySQL and the drivers is beyond the scope of this article. Pick the one that satisfies your requirements and install it using the "go get" tool (e.g. "go get github.com/ziutek/mymysql"). Add the necessary imports to your Go files. Run "godep save" to add the driver code to the godep repository in your project.
As mentioned earlier, all of the necessary connection information for MySQL can be found in the VCAP_SERVICES environment variable. Notice that when you checked your dashboard for the credentials they showed up in a json format. You need to parse out the particular information you need for MySQL using the json parser. Check out the following code snippet to see how I extracted the information from the ClearDB service. If you chose the MySQL service you will find that you can parse the details in a very similar way.
Now that you have the service and driver set up you can begin writing your code to populate and query your MySQL database. When you have finished writing your code you can deploy it by running "cf push" command.
Serving Static Content
Static content such as HTML files, templates and Javascript can be included in your package alongside your Go source code. It is automatically uploaded to Bluemix when you deploy. Also, when your Go program is executed the current working directory is the location where all of your files are uploaded. If you need to serve static content you can open the files using relative paths such as "static/index.html."
If you find that your static files cannot be opened by your application check your .cfignore files. They might be excluding files from being uploaded by cf push.
It is important to ensure that your static content handler will not provide access to sensitive files from your Bluemix application such as log files with sensitive passwords. The easiest way to do this is to disallow absolute paths and relative paths with ".." segments in it.
If you find that your static files cannot be opened by your application check your .cfignore files. They might be excluding files from being uploaded by cf push.
It is important to ensure that your static content handler will not provide access to sensitive files from your Bluemix application such as log files with sensitive passwords. The easiest way to do this is to disallow absolute paths and relative paths with ".." segments in it.
Sending Email
There is an email service in Bluemix called Sendgrid. It can be accessed using Go's standard net/smtp package. If you create a Sendgrid service and bind it to your application you will find that it provides the necessary host and credentials in the familiar VCAP_SERVICES environment variable along with the MySQL information. Sendgrid appears to use port 25, which is the default SMTP port. You will need to hard-code this port when using Go's smtp package.
Conclusion
Now that you can access a database, use third-party Go libraries, provide static content and send email you can create a full-featured application on Bluemix. Along the way you have learned about important patterns such as the VACP_SERVICES environment variable where the credentials for all of the bound services are communicated to your application. These patterns should enable you to interact with many of the services offered on BlueMix such as mobile and analytics should you require those capabilities.
For an example of a Go application that runs in Bluemix and uses many of the services covered in this article check out the "lunchsoccer" application published on IBM DevOps Services.