Skip to content

Latest commit

 

History

History
142 lines (91 loc) · 4.85 KB

NOTES.md

File metadata and controls

142 lines (91 loc) · 4.85 KB

Skeleton Chi Blog

Work in Progress.

Unlike Django & Rails, chi does not enforce structure. This is an attempt to layout such a structure.

Directory Layout

models/
views/
services/
app/
config/
middleware/
    auth.go
templates/
public/
main.go =>  main() & init()
Makefile =>  run app, run tests, 

# generated by Makefile
_build/

Conventions

init()

  • Initializes logging
  • Runs Gorm migrations

main()

Pulls the app (app/) and starts the http listener.

Optional flag is used to start docgen. See here for an example.

Views

HandlerFuncs should always be lowercased (i.e. "private") with the first word being the method (e.g. "POST", "GET", "PUT", etc).

Template names should be prefixed by the dominant model if there is one. E.g. post_detail.html.tmpl, post_list.html.tmpl, post_new.html.tmpl, etc.

Database management

Optimization is the root of all bugs. That means gorm is leveraged without any functions on top (e.g. no GetPostByUuid(...)). In the future, you'd probably remove this so as to leverage raw SQL queries.

We can, in fact, share the database object. This is because, under the covers, Gorm uses the sql.DB which explicitly allows for this. It will create and free connections internally. More docs here.

Testing

Write utility functions! Type enforcement becomes annoying with golang.

POST/PUT/PATCH requests will all need a Content-Type: application/x-www-form-urlencoded added to the header.

It's not worth testing every folder. One of the folders that really doesn't matter is /templates.

Functions should do one thing and with little to no side effects. This makes it easy to follow logic around. Tests are an exception! They can test multiple functions at once. This is allowed because it more closely resembles how your program works. It also allowed for daisy chaining how functions can work (e.g. you create and then query, which might be testing two separate operations). In practice, your tests should run entirely correctly or not at all so any breaking functionality will break a test somewhere that you can then diagnose and fix.

Linting

Two linters are used: staticcheck and golangci-lint. Both are given stock configurations but can be configured to taste.

The list of available checks for staticcheck are listed here.

The list of available checks for golangci-lint are listed here. Unlike staticcheck, it is not installed by default via the make install.

Middleware Order

  1. Profiler
  2. Logger -- though maybe this?
  3. Compress
  4. cors
  5. CleanPath
  6. StripSlashes
  7. RealIP
  8. gorilla/sessions

Sessions Middleware

If using encryption, encryption keys need to be exactly 16, 24, or 32. Authentication keys can be any length.

Model-View-Controller (MVC)

Views (views/) take in the request, pass all business logic to the controller (services/) which can use models (models/) to persist and modify the underlying data. They then return to the view, which populates a template (templates/) -- or not -- and returns a response.

Views never handle business logic. That is solely the job of a service. This makes it easier to not only debug but also build because we can "stub" out the business logic when making sure the view logic looks correct.

The solely exception to above are value for templating. This includes the count of a list of posts submitted.

Things to Do

See TODO.md

Errata Notes

  • Write tests for models as examples of what to do, don't bother with special functions to do specific work because you don't know the domain space yet

  • using names to make sure that pieces don't get accessed outside of where they should (app.session)

  • do you test that auth works or not? Only for end-to-end. Because services are separated from routes, this means you can test business logic separately. A helper function should be written for making the authentication process simple.