A few weeks ago, I set out to learn a bit of go, and rewrite my blog software. Previously I had been using a wordpress install with a DIY template, and some custom plugins. This worked pretty great for quite a long time, but I wanted to learn something new.
I played around with some javascript frameworks, and also experimented a bit with Jekyll to generate static pages from markdown for github pages hosted content. This was pretty good but I really wanted to play around with endpoints as well.
When I first started this project, I knew I wanted a JSON api which I could use to create, edit and delete posts. I also wanted to be able to query for posts. Eventually I wanted to have an extension to the api to support comments. In order to keep everyone from being able to post, I need authentication and authorization. I also eventually wanted to be able to add files to posts, again using the JSON api.
The idea with this would be that I could then use whatever I liked for the front-end / templating. Originally I started with a single page app approach using a javascript framework for the front-end, but eventually when I discovered how the go html templating worked, I decided to abandon that and keep everything server-side.
The gin framework is used for routing. It's been mostly really quick and easy to learn - with a few annoyances (for instance if I want to have a path with `posts/:yyyy/:mm/:dd/:slug`, I can't also have a path with just `posts` or there will be a conflict. I think there are some ways around it, but its not quite as clean as I was expecting.
I have two sets of routes, one for the JSON api and one for the HTML api, which renders the templated UI.
For authentication, I use the github oAuth to get an access token. I also retrieve the github profile, and use the username provided back from github to decide whether to provide admin access or not.
To store posts, to be quick and dirty, for now I'm just using sqlite. To provide a mapping between go structs and the database schema, I'm using gorm. Right now, there are `users`, `posts`, and `tags` - but eventually I'll support `comments` or something. I was also considering files to keep track of uploaded `files` / metadata, but for now - I just dump them into an `uploads` directory.
For deployment, I have set the go server to run in a docker container. When I cut a new `release` of the software, I build a new docker image which is a `go build` of the server, and then push it to docker hub. On my server, I have `dev` and `www` subdomains which point to different docker images - one where I can test first, and then once I'm confident roll out to `www`. I've got all this setup using `saltstack`. Both are actually hosted on the same machine behind an `nginx proxy` (I didn't bother hosting via `aws` or `gcp` because I wanted to be as cheap as possible and am just hosting on a spare machine at home).
So far its been fun to learn a bit about go, and the site seems to be decent at staying online. Right now, I've got a setup to run tests when I push using Github actions (although admittedly the coverage is pretty low). I'll be working to increase coverage now that the code is becoming more mature shortly. I'm sure there are many security vulnerabilities which I have not thought about yet, so I wouldn't use this for production anything. I've also got a TODO list in the readme with features I'm still adding. In the meantime, this should work well enough to start blogging again. Feel free to try out the code yourself, submit PRs, etc. if you want to build on it.