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": {}
}

%%