summaryrefslogtreecommitdiff
path: root/view/recipe.go
AgeCommit message (Collapse)Author
2024-10-24view: Order ingredient summary by ingredient namexengineering
This makes it easier to write a shopping list for the required ingredients.
2024-10-23Switch to http.Handlerxengineering
The used `func(http.ResponseWriter, *http.Request)` return values made the HTTP handler factory functions quite unreadable. Thus it is switched to the http.Handler type.
2024-10-22Remove github.com/gorilla/mux dependencyxengineering
The reason for the introduction of this dependency was that it was easy to setup routes with HTTP method restrictions. Since Go 1.22 this feature is part of the standard library. Method restrictions are part of the patterns used to register routes [1]. [1]: https://pkg.go.dev/net/http#hdr-Patterns-ServeMux
2024-10-13model: Replace global db variable by custom typexengineering
Reducing global variables makes it easier to understand functions independently of the rest of the code. Adding the new model.DB type as a custom variant of the sql.DB type makes it possible to write methods for the database which makes the code way more readable.
2024-09-11Apply go fmt to all source filesxengineering
This applies default Go code style recommendations.
2024-05-09Remove default recipe namexengineering
To avoid not clickable recipes on the /recipes page a default name used to be inserted on recipe creation. This was not a proper fix for the problem and also was annoying that the user first had to remove the default recipe name. This commit removes this default name.
2024-05-08Introduce model.Transaction()xengineering
It is a very common pattern that some function needs to access the database and wants to wrap all the actions into one transaction. The advantage of a transaction is that it is ACID: - atomic - consistent - isolated - durable In Go it is required to request a new transaction, execute functionality on it and handle rollback or commit of this transaction based on the success of the operation. All this and the error handling can be written down in the model.Transaction() function exactly once. The full signature of it is: func Transaction(f func(*sql.Tx) error) error It requires a function or closure passed as argument which takes the transaction (*sql.Tx) and returns an error which might be nil. This is very generic. It is applied to: - injecting test data - database migrations - data read requests - data write requests
2024-04-07model: Add helper function for safe CRUDxengineering
This removes the redundant setup of a database/sql.Tx in each HTTP handler.
2024-04-06model: Always pass *sql.Tx to CRUD methodsxengineering
When nesting objects like steps into other objects like recipes it is required to pass a *sql.Tx value to the CRUD methods of the inner object to be able to roll back the whole transaction. The top level object used to be responsible for the creation of this *sql.Tx inside its CRUD methods. This is now moved to the caller of the CRUD methods (here the HTTP handler function). The advantage is that all CRUD methods now accept a *sql.Tx as only argument which makes those methods more consistent.
2024-03-03view: Provide recipe deletionxengineering
2024-03-03view: Add 'Read' suffix to function namesxengineering
This reflects that these HTTP handler functions implement one of the four CRUD methods create, read update and delete.
2024-03-03view: Replace edit by view parameterxengineering
The old edit URL parameter allowed to select one different HTML template. A more generic approach is to provide a view parameter which allows to use multiple alternative HTML templates for the same data defined by the Go struct. This makes implementing additional pages like a confirm page for recipe deletion easier.
2024-03-03model: Use only string types for modelsxengineering
When a HTML form is converted to JSON by JavaScript using `FormData()`, `Object.fromEntries()` and `JSON.stringify` the data type is always `string`. This does not match the Go struct definitions using multiple types including e.g. `int`. There are several options to solve this conflict: 1. use only strings in Go struct definitions 2. write custom functions to parse string-based JSONs to Go structs 3. implement custom functions in JS to use `number` type if possible Option 3 seems to be a very clean solution. Nevertheless it is limited by the fact that JSON anyway has a way more limited type system than Go. So the types used in Go cannot be used and this would reduce this option to a variant of option 2. Option 2 requires significant effort per struct inside the model package. Every object which is transferred via JSON and serialized into Go structs would require a second struct definition with string types and a conversion function. This does not scale. Thus option 1 seems to be the best fit. The reasons for using types like `int` or `bool` are: - less memory consumption than `string` in most cases - implicit data validation (e.g. enforcing positive numbers with `uint`) - better compatibility with certain APIs which rely on e.g. `int` The first argument is not so relevant in this use case. The amount of required memory is still quite small for servers. Implicit data validation is a good thing but not enough. There should anyway be validation method which has to be called on CRUD methods and JSON deserialization.
2024-02-15view: Add edit view for model.Recipe typexengineering
2024-02-13view: Implement GET handler for model.Recipexengineering