URL-Shortener-Design-diagram.excalidraw
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
URL Shortener — System Architecture Diagram
Text Elements
Write Path ^write-label Client ^client-write POST /shorten {longUrl} ^write-req API Gateway ^apigw-write Shortening Service ^shorten-svc Base62 encode ^base62-label KV Store ^kvstore-label key=shortCode, val=longUrl ^kvstore-sub 201 {shortUrl} ^write-resp ID Generator ^id-gen-label unique counter ^id-gen-arrow-label
Read Path ^read-label Client ^client-read GET /{shortCode} ^read-req API Gateway ^apigw-read Redirect Service ^redirect-svc Cache (Redis) ^cache-label cache-aside: check first ^cache-note longUrl ^kv-resp-label 301 Redirect ^redirect-resp
Write: encode + store | Read: lookup + redirect (cache-aside for hot URLs) ^annotation
%%
Drawing
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [
{
"id": "write-label",
"type": "text",
"x": 40,
"y": 20,
"width": 160,
"height": 24,
"text": "Write Path",
"fontSize": 18,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "top",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "client-write",
"type": "rectangle",
"x": 40,
"y": 54,
"width": 100,
"height": 44,
"strokeColor": "#1e1e1e",
"backgroundColor": "#f1f3f5",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "client-write-text",
"type": "text",
"x": 55,
"y": 68,
"width": 70,
"height": 20,
"text": "Client",
"fontSize": 14,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-client-apigw-write",
"type": "arrow",
"x": 140,
"y": 76,
"width": 90,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [90, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "POST /shorten",
"fontSize": 11,
"strokeColor": "#1e1e1e"
}
},
{
"id": "apigw-write",
"type": "rectangle",
"x": 230,
"y": 54,
"width": 120,
"height": 44,
"strokeColor": "#1971c2",
"backgroundColor": "#e7f5ff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "apigw-write-text",
"type": "text",
"x": 245,
"y": 68,
"width": 90,
"height": 20,
"text": "API Gateway",
"fontSize": 14,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-apigw-shorten",
"type": "arrow",
"x": 350,
"y": 76,
"width": 80,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [80, 0]],
"startArrowhead": null,
"endArrowhead": "arrow"
},
{
"id": "shorten-svc",
"type": "rectangle",
"x": 430,
"y": 44,
"width": 160,
"height": 64,
"strokeColor": "#1971c2",
"backgroundColor": "#d0ebff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "shorten-svc-text",
"type": "text",
"x": 445,
"y": 54,
"width": 130,
"height": 40,
"text": "Shortening Service\nBase62 encode",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-shorten-kv",
"type": "arrow",
"x": 590,
"y": 76,
"width": 80,
"height": 0,
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [80, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "store",
"fontSize": 11,
"strokeColor": "#2f9e44"
}
},
{
"id": "kvstore",
"type": "ellipse",
"x": 670,
"y": 40,
"width": 160,
"height": 80,
"strokeColor": "#2f9e44",
"backgroundColor": "#ebfbee",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "kvstore-text",
"type": "text",
"x": 685,
"y": 54,
"width": 130,
"height": 40,
"text": "KV Store\nkey=shortCode\nval=longUrl",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-write-resp",
"type": "arrow",
"x": 350,
"y": 108,
"width": -310,
"height": 0,
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"strokeStyle": "dashed",
"opacity": 100,
"points": [[0, 0], [-310, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "201 {shortUrl}",
"fontSize": 11,
"strokeColor": "#868e96"
}
},
{
"id": "id-gen",
"type": "rectangle",
"x": 430,
"y": 130,
"width": 160,
"height": 40,
"strokeColor": "#e67700",
"backgroundColor": "#fff9db",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "id-gen-text",
"type": "text",
"x": 445,
"y": 142,
"width": 130,
"height": 20,
"text": "ID Generator",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-idgen-shorten",
"type": "arrow",
"x": 510,
"y": 130,
"width": 0,
"height": -22,
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [0, -22]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "unique counter",
"fontSize": 10,
"strokeColor": "#e67700"
}
},
{
"id": "read-label",
"type": "text",
"x": 40,
"y": 210,
"width": 160,
"height": 24,
"text": "Read Path",
"fontSize": 18,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "top",
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "client-read",
"type": "rectangle",
"x": 40,
"y": 244,
"width": 100,
"height": 44,
"strokeColor": "#1e1e1e",
"backgroundColor": "#f1f3f5",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "client-read-text",
"type": "text",
"x": 55,
"y": 258,
"width": 70,
"height": 20,
"text": "Client",
"fontSize": 14,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-client-apigw-read",
"type": "arrow",
"x": 140,
"y": 266,
"width": 90,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [90, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "GET /{shortCode}",
"fontSize": 11,
"strokeColor": "#1e1e1e"
}
},
{
"id": "apigw-read",
"type": "rectangle",
"x": 230,
"y": 244,
"width": 120,
"height": 44,
"strokeColor": "#1971c2",
"backgroundColor": "#e7f5ff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "apigw-read-text",
"type": "text",
"x": 245,
"y": 258,
"width": 90,
"height": 20,
"text": "API Gateway",
"fontSize": 14,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-apigw-redirect",
"type": "arrow",
"x": 350,
"y": 266,
"width": 80,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [80, 0]],
"startArrowhead": null,
"endArrowhead": "arrow"
},
{
"id": "redirect-svc",
"type": "rectangle",
"x": 430,
"y": 244,
"width": 160,
"height": 44,
"strokeColor": "#e67700",
"backgroundColor": "#fff4e6",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "redirect-svc-text",
"type": "text",
"x": 445,
"y": 258,
"width": 130,
"height": 20,
"text": "Redirect Service",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "cache",
"type": "rectangle",
"x": 550,
"y": 320,
"width": 140,
"height": 50,
"strokeColor": "#c92a2a",
"backgroundColor": "#fff5f5",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"strokeStyle": "dashed",
"opacity": 100
},
{
"id": "cache-text",
"type": "text",
"x": 565,
"y": 335,
"width": 110,
"height": 20,
"text": "Cache (Redis)",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#c92a2a",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-redirect-cache",
"type": "arrow",
"x": 510,
"y": 288,
"width": 110,
"height": 36,
"strokeColor": "#c92a2a",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"strokeStyle": "dashed",
"opacity": 100,
"points": [[0, 0], [110, 36]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "check cache",
"fontSize": 10,
"strokeColor": "#c92a2a"
}
},
{
"id": "arrow-redirect-kv",
"type": "arrow",
"x": 590,
"y": 266,
"width": 85,
"height": 0,
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [85, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "lookup",
"fontSize": 10,
"strokeColor": "#2f9e44"
}
},
{
"id": "arrow-kv-redirect-resp",
"type": "arrow",
"x": 755,
"y": 290,
"width": -165,
"height": -14,
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"strokeStyle": "dashed",
"opacity": 100,
"points": [[0, 0], [-165, -14]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "longUrl",
"fontSize": 10,
"strokeColor": "#2f9e44"
}
},
{
"id": "arrow-redirect-client-resp",
"type": "arrow",
"x": 350,
"y": 298,
"width": -310,
"height": 0,
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"strokeStyle": "dashed",
"opacity": 100,
"points": [[0, 0], [-310, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "301 Redirect",
"fontSize": 11,
"strokeColor": "#868e96"
}
},
{
"id": "annotation",
"type": "text",
"x": 40,
"y": 400,
"width": 760,
"height": 20,
"text": "Write: encode + store | Read: lookup + redirect (cache-aside for hot URLs)",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "top",
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
}
],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}%%