Go, Gin, React, and GORM part 1

versions:
go 1.12
node v11.10.0
npm/npx 6.7.0
create-react-app 1.5.2

A Simple Blog App

I recently started learning Go more in depth and have been diving a bit more into the web frameworks that are popular with it. Coming from a Node.js background, I wanted to see how a compiled language works when it comes to the backend on a simple CRUD app, so why not build the standard blog site, right? After all, setting up a simple blog site using a full stack requires that you have a persistent data storage method (databases and the like), some lovely api endpoints that serve up content to your front-end and change data in the storage layer, and lastly a snazzy front-end with buttons and content and interactive such stuff. Because what’s a database without some sort of way to make it cool looking.

Back-end

File structure

Eventually our structure will look something like this but at this point I only had a client and server folder under the root and a main.go file under server. More about the rest of those files and folders later.

Screen Shot 2019-03-18 at 11.31.51 AM

After structuring the app, I initialized my git repo:

git init

git add .

​​git commit -m 'adds code and message about initializing'

git remote add origin remote-url-path

git push -u origin master

Getting Up and Running

Then, I started up my main.go file

The above code is a super simple start to using Gin in Go. All you have to do is define the router and use it. Here we are using the default router and then serving up the index.html file from the client. The index.html file is where we will build the React app in a second.

API Layer

Api’s don’t take too much to get setup either. I set up several routing groups in just a few minutes using the router.Group() method.

Quite a bit more in this revised file, and while it looks intimidating at first, it’s actually very manageable. Let’s break it down. First, I created an api group called “api” and it’s routing path is “/api”. Every call that gets made to the server will route through “/api” first in this setup. Secondly, I make a subgroup called blog that uses the api base group as its mounting point. So if I wanted to access all the blog posts, I would use the path “/api/blog/” and send a GET request. If you run go run main.go here you’ll get an awesome debugger and http server running on port 5000 and you can go to the browser to make sure it’s working. I just put some basic html in my index.html file so I could see I was getting the content there.

At this point this app is ready for some curl calls or some messing around in Postman (or your preferred api testing environment).

Test: curl :5000/api/

Result: {message: base route reached}

Now, as it is all of these endpoints only send a message back in JSON format right now. You can send data in many different ways, but as our React front-end will eventually need a JSON format to consume the endpoints, we might as well start there.

Database – a persistent memory layer

For our database I’m using a mySQL docker image.

Then run docker-compose up and you’ll have a containerized database ready to accept some data! I ❤ docker

Connecting HandlerFuncs to the Database

For an ORM I picked Gorm. They have a great module that you can get from running

go get github.com/jinzhu/gorm

and then you’ll want to add the dialect you want to use.  I chose to use mySQL.

Now that there is a connection to the database we can start setting up all the CRUD operations. The Context type is a struct that contains the signature from the net/http package as well as a few other fun things. Thanks gin.

(w http.ResponseWriter, r *http.Request)

The endpoints on the blog group are using an externally defined function handlers from the handler.go file.

Models

Of course we also need to have a models file to describe our structure when it goes into the database.

This file contains a struct called BlogPost that is used to describe the structure Gorm will translate into mysql for us. The gorm.Model there gives us an id field as well as some other helpful database fields, so I’ve commented out the ID in the struct for now. You don’t have to have the gorm.Model, but I found it helpful.

Just a side note here, Gormigrate is a helpful Gorm integration that can alleviate some of the database migration issues that you might find with Gorm. I used Gormigrate to setup the database and gorm.Automigrate(&BlogPost{}) to keep the migrations up to date; however, I’ve seen a lot of suggestions that using Gormigrate only for migrations is best practice. I’m still playing with it so I haven’t made up my mind, but the suggestions are pretty convincing.

Next up the create-react-app front-end

 

References and further reading

Medium – @cgrant — Developing a Simple CRUD Api with Go, Gin, and Gorm

Medium – @benbjohnson – Structuring Applications in Go

https://blog.depado.eu/post/gorm-gotchas#toc_6

https://godoc.org/gopkg.in/gormigrate.v1

http://doc.gorm.io/database.html#migration

https://www.alexedwards.net/blog/serving-static-sites-with-go

http://gorm.io/docs/migration.html

http://doc.gorm.io/advanced.html#compose-primary-key

https://godoc.org/github.com/gin-gonic/gin#Context

http://doc.gorm.io/crud.html#query

http://nauvalatmaja.com/2016/04/15/function-composition-in-go/

https://godoc.org/github.com/gin-gonic/gin#HandlerFunc

https://www.socketloop.com/tutorials/golang-pass-database-connection-to-function-called-from-another-package-and-http-handler