Thursday, 8 April 2021

Re-Starting with Go

 I am once again looking at Go, after a break of over eight years. I did not get that far back then, and as I recall the stumbling block was that you can only pass one object (struct in Go) to a template.

My Ruby on Rails project has got every bigger, as indeed has Ruby on Rails itself, with my WAR files now weighing in at 65 Mb, which seems huge to me, and I am getting complaints about speed. So I am at least looking at migrating bits to Go.

I did look at Rust but getting Rust to connect to a PostgreSQL database proved very temperamental. With that in mind, my first concern was getting Go to connect.

Two useful tutorials:

https://www.calhoun.io/connecting-to-a-postgresql-database-with-gos-database-sql-package/

https://www.alexedwards.net/blog/organising-database-access

It seems to be as simple as adding the driver to your go.mod file (which unlike other Rust, Node.js and Rails is done through the command line, rather than editing the file yourself):

go get -u github.com/lib/pq

In your file, import it (the underscore is because the import is really just registering the driver, you do not actually need to access it):

import (
  "database/sql"
  _ "github.com/lib/pq"
)

Then open the connection:

db, err := sql.Open("postgres", "host=localhost port=5432 user=user dbname=godatabase sslmode=disable password=password")

Interacting with the database is much more low level than Rails.

Thursday, 6 December 2012

File Structure for a Go Web App

Starting to build a web app, I found precious little suggesting best practice with Go (or "golang" for search engines). This page therefore reflect what I am trying at the moment, somewhat influenced by my experiences with Rails, as well as this web page:

http://stackoverflow.com/questions/9573644/go-appengine-how-to-structure-templates-for-application

/
|
+---- app.yaml
+- static/
|    |
|    +- images/
|    |    |
|    |    +---- logo.png
|    |
|    +- stylesheets/
|         |
|         +---- styles.css
|
+- templates/
|    |
|    |
|    +---- base.html
|
+- app/
|    |
|    |
|    +---- http.go
|    +- templates/
|    |    |
|    |    +---- index.html
|    |
+- post/
|    |
|    |
|    +---- http.go
|    +---- model.go
|    +- templates/
|    |    |
|    |    +---- index.html
|    |    +---- compose.html
|    |    +---- edit.html
|    |    +---- show.html
|    |
etc.


The first templates folder holders the template with the header and any HTML common access the site. Each page will have its HTML inserted into this (like layouts in Rails).
The app folder is for the root page, /, so (for me) has no model, just an index page.
The post folder is an example of a folder for a model called post. In Ruby I would have a template called new, but new is a keyword in Go, so here I used compose instead (because I want the template name to correspond to the function).

No configuration

There is no global config folder or file besides app.yaml. Each model registers itself to accept specific HTTP requests, so an equivalent to routes.rb is not required. The datastore makes database configuration and migrations unnecessary. Go automatically runs any init() function in a package on start-up, so initialisation is better done there.

The up-shot is that you still have to do some configuration, but it is done locally in the model folder, which does seem a better way to organise it. Each model can be an isolated unit that you could drop into another application just by copying the folder across.

The app.yaml file

This is used by Google App Engine to configure the web app. It states the language used, and also has some URL pattern-matching that determines how web requests are handled. For a Python application, this can be used to direct requests to specific scripts, but it seems that for Go, you send them all to a script called _go_app. You can use it to distinguish between dynamic pages and static pages, and to restrict access to
either users logged in only and administators only, but once set up, you can probably just forget about it (except perhaps updating the version number).

https://developers.google.com/appengine/docs/go/config/appconfig

Static files

As the app.yaml file uses the term "static", I think it makes sense to keep all these in a single directory with that name, and to have subdirectories for files within that (images, stylesheets, etc.). To access an image, the request will be /images/logo.png, not /static/images/logo.png, by the way.

Wednesday, 5 December 2012

Starting with Go

Recently I have been experimenting with Go (or "golang" for search engines), a programming language from Google. My ultimate aim is to create web applications on Google Web App, and I had been planning on doing that in Ruby (my corresponding Ruby blog is here), using Rails 3, but Ruby support seems to have faltered with no updates in over a year.

The Go language is based here:
http://golang.org/

Go is a compiled language that looks to have been designed for simplicity (in the sense of a reduced set of keywords and constructs). It is not object-orientated; last time I used a language that was not object-orientated it was QBASIC about 15 years ago...

Some other links:
http://golang.org/doc/effective_go.html
http://golangtutorials.blogspot.co.uk/2011/05/table-of-contents.html

A simple but good IDE can be found here:
http://code.google.com/p/liteide/

Go has no framework analogous to Rails, but it does have some nice features built in, and there is a very simple tutorial to get a guest book project (similar to the classic Ruby on Rails tutorial) up and running.

https://developers.google.com/appengine/docs/go/gettingstarted/introduction

In some regards, the tutorial is better than the Ruby on Rails equivalents as it includes a system for users to log in before posting (which is trivial in Google App  Engine), and it ends with a fully uploaded and operational application (again, uploading is very easy on Google App Engine).

However, the next steps are not so clear, hence, I am "struggling with go".