Whoever shares a short link wants to know how many people opened it. Every visit through the short link is a click, so each link must now remember two things: its URL and its number of clicks.
A map of struct pointers: the starting code gives each link a struct, Link, with the fields URL and Clicks, and links is now a map[string]*Link. &Link{…} makes a link and gives its address, so a handler can change the link right where the map keeps it. For example, with pages instead of links:
type Page struct {
Title string
Views int
}
var pages = map[string]*Page{}
pages["home"] = &Page{Title: "Home", Views: 0}
pages["home"].Views += 1
fmt.Println(pages["home"].Views) // 1
Count the click in the /{code} handler, then redirect to the link's URL. Then a new handler, GET /links/{code}/stats, answers a link's numbers. Looking at the stats is not a click.
After three POST /links made the codes 1, 2 and 3, and the visits GET /1, GET /1 and GET /2 (each still answers 302 to its URL), your app must answer:
GET /links/1/stats → 200 {"clicks": 2, "code": "1", "url": "https://www.python.org/downloads/"}
GET /links/2/stats → 200 {"clicks": 1, "code": "2", "url": "https://en.wikipedia.org/wiki/URL_shortening"}
GET /links/3/stats → 200 {"clicks": 0, "code": "3", "url": "https://flask.palletsprojects.com/en/stable/quickstart/"}
GET /links/4/stats → 404 {"error": "Link not found"}
Your task: in the /links handler, store each link as a &Link with its URL and Clicks starting at 0. In the /{code} handler, below the 404 check, count the click, then redirect to the link's URL. Below that handler, add GET /links/{code}/stats, with the same 404 for unknown codes, answering the code, the URL and the clicks with 200.
Assignment
Follow the Coding Tutorial to count the clicks and add the stats handler.
Hintlinks[code] is a *Link now, so the URL is one level deeper, in its URL field. The stats mix strings and a number, so answer them in a map[string]any.
Free plan: 30 tutor messages. PRO is unlimited.
