1. 3

I’m the author of this repo and I’m submitting it to solicit feedback and opinions.

  1. 2

    This looks like a good start! Since you’re soliciting comments (and this might be something I’m interested in using), I’ve got a few comments.

    1. The Dockerfile mixes different Linux distros (and different libc implementations). This most likely won’t cause issues, but definitely could. Usually, when I build images, I use golang:1.x-buster for building and debian:buster-slim for the base image.
    2. I personally prefer chi because it makes it a little easier to use context.Context and middlewares, but that isn’t necessarily a great thing.
    3. Another personal preference, I generally do most configuration via environment variables rather than config so viper is super heavyweight for my use case, though if you want to do something with consul or other remote config, viper can be good. I use godotenv and gitignore/dockerignore the .env file.
    4. I’ve used github.com/markbates/pkger for asset bundling. It has a nice way of handling things so in dev it can read from disk, but when bundled it reads from the binary. However, I don’t know if I’d recommend this yet because there’s a draft for a FS interface and built-in file embedding
    5. In ORM vs manual, I generally lean towards manual using golang-migrate for migrations and sqlx to reduce boilerplate. I don’t mind gorm, but it doesn’t return errors in many cases (you have to check result.Error or conn.Error) so you have to be careful about checking them when you’re supposed to (https://gorm.io/docs/error_handling.html). It can reduce boilerplate, but it’s super easy to miss an error somewhere.
    6. For git stuff, there’s not a perfect command, but I like git describe --always --dirty=-dirty --exclude="*" to get the current hash (it also appends -dirty if there are uncommitted changes). Optionally, you can combine that with git branch --show-current to include the current branch as well (this is useful if you have different builds on different branches like prod and staging).
    7. What’s the extra static linking stuff for in the Makefile? I haven’t seen that used anywhere else for Go projects
    8. For templates, I generally stick to the built-in Go template/html package until it isn’t enough.

    Stuff that might be useful but not for everyone:

    • Proper handling of the Authorization header and/or some sort of auth_token query arg. At least for APIs, this is something that isn’t handled properly.
    • Dev mode where templates are loaded from the disk when developing, but bundled in for prod.
    • Password handling - I’d love to see something like passlib for Go, but it’s a fairly complex project and doesn’t translate super well to Go.

    There are a lot of things that I’d like to build in to a “simple” http toolkit (mostly stuff I mentioned above)… I think this post might actually get me to try working on that again.

    1. 2

      This is super useful feedback, thank you!

      Some of the stuff was holdovers from previous projects with slightly different requirements, a sort of boilerplate inertia. You’re right that I should probably pull out viper and redo the Makefile and Dockerfile from scratch.

      This is exactly the kind of feedback I need. Thank you!

      1. 1

        Glad to hear it’s helpful! I definitely got a some ideas from it I might snag for some of my own projects.

    2. 1

      Any specific reason you have /httpserver rather than /internal/httpserver?

      1. 2

        Not the author, but I personally don’t think there’s always value to hiding all the packages in internal if your exported artifact is a binary… it adds one extra path component to the import path everywhere with minimal benefit. As an example, I’d rather import github.com/belak/something/models rather than github.com/belak/something/internal/models.

        I agree that there’s value for libraries, but this is specifically an http server template.