# README
Snippetbox
Note:- This readme file contains the important concepts that I learnt while building this application.
Servemux:
-
Router is equivalent to servemux in go. Usually we have one servemux for our app containing all our routes.
-
Request goes to the => Go Server (passes it to) => servemux's ServeHTTP() method=> in-turn calls handler's ServeHTTP() method
-
servemux treats "/" as catch-all.
-
Goʼs servemux supports two different types of URL patterns: fixed paths (/api/users) exact match and subtree paths (/api/users/) wildcard match. Fixed paths donʼt end with a trailing slash, whereas subtree paths do end with a trailing slash.
-
So, for the sake of security, itʼs generally a good idea to avoid DefaultServeMux.
-
In Goʼs servemux, longer URL patterns always take precedence over shorter ones. Request URL paths are automatically sanitized. host-specific maths are precedenced than non-host specific patterns.
-
All incoming HTTP requests are served in their own goroutine. Go Server is Concurrent!
Project Structure & Packaging
-
The cmd directory will contain the application-specific code for the executable applications in the project. It scales nicely to add another app later on (cmd/cli).
-
The ui directory will contain the user-interface assets used by the web app.
-
Packages which live in internal directory (helpers|db models) can only be imported by code inside our snippetbox project.
-
The go.sum file contains the cryptographic checksums representing the content of the required packages.
-
go mod download is used to download the exact versions of all the packages that your project needs.
-
go mod verify is to ensure that nothing in those downloaded packages has been changed unexpectedly.
-
To upgrade to latest available minor or patch release of a package, you can simply run go get with the -u flag.
-
go mod tidy, which will automatically remove any unused packages from your go.mod and go.sum files.
Templating
- {{template}} action is used to invoke one template from another. But Go also provides a {{block}}...{{end}} action which you can use instead.
File Server
- Go has built-in http.FileServer handler which you can use to serve files over HTTP from a specific dir.
- It sanitizes all request paths by running them through the path.Clean() function before searching for a file.
- Range requests are fully supported. This is great if your application is serving large files and you want to support resumable downloads.
- The Last-Modified and If-Modified-Since headers are supported.
Dependency Injection
- Most web apps will have multiple dependencies that their handlers need to access (db conn, centralized err handlers...). How can we make any dependency available to our handlers?
i. use global vars (❌) ii. inject dependencies (✅).
For apps where all handlers are in the same package, a neat way to inject deps is to put them into a custom application struct, and then define your handler functions as methods against application.
Mysql Database Driver
- The sql.Open() function returns a sql.DB object. This isnʼt a database connection — itʼs a pool of many connections.
- The connection pool is safe for concurrent access.
- The connection pool is intended to be long-lived.
- The sql.Open() function doesnʼt actually create any connections, all it does is initialize the pool for future use.
- You can think of a Database model as a service layer or a data access layer.
Queries
- DB.Query() is used for SELECT queries which return multiple rows.
- DB.QueryRow() is used for SELECT queries which return a single row.
- DB.Exec() is used for statements which donʼt return rows (like INSERT and DELETE).
Transactions
- Itʼs important to realize that calls to Exec(), Query() and QueryRow() can use any connection from the sql.DB pool. Even if you have two calls to Exec() immediately next to each other in your code, there is no guarantee that they will use the same database connection.
- Sometimes this isnʼt acceptable. For instance, if you lock a table with MySQLʼs LOCK TABLES command you must call UNLOCK TABLES on exactly the same connection to avoid a deadlock.
- To guarantee that the same connection is used you can wrap multiple statements in a transaction.