Home/Low-level design/Recipe Manager

Recipe Manager

Permissions and immutable revision history

Immutable revisions separate historical truth from the current-name index. Updating or rolling back appends a revision, while renaming frees only the old current name. A historical name can be occupied by another recipe and block rollback.

go
ingredients := []string{"salt", "water"}
snapshot := append([]string{}, ingredients...)
snapshot[0] = "pepper"
fmt.Println(ingredients[0]) // salt: detached slice

Permissions are explicit capabilities: read does not imply write and write does not imply read. Validate content before permission checks when the API requires a structural error even for an unauthorized caller. Copy nested ingredients and steps both when accepting content and when returning a revision. Otherwise a caller can rewrite history without going through Update.

Go models this service with a struct and pointer-receiver methods. Constructor functions return a pointer; validation failures return errors rather than panicking. Scalars in snapshot structs are copied by value. Maps, slices, and optional pointers still require detached copies when crossing the service boundary. Go maps do not have key iteration order; use ordered slices for ranked results. There are no threads, persistence, wall-clock reads, or external side effects in this exercise.

Put it into practice

Implement the exercise in a full-screen workspace, then run its tests.

Open practice
Next lessonMessage Broker