or run

npx @tessl/cli init
Log in

Version

Files

tile.json

task.mdevals/scenario-8/

URL Shortener API

Build a simple URL shortener API service that handles different path patterns for creating, retrieving, and managing shortened URLs.

Requirements

Create a Koa application with the following routes:

  1. Create Short URL: Accept POST requests to create a new shortened URL

    • Path: /shorten
    • Request body contains { "url": "https://example.com" }
    • Response: { "short": "abc123" } with status 201
  2. Redirect to Original URL: Accept GET requests with a short code to redirect

    • Path: /r/:code
    • Extracts the short code from the path
    • Response: Redirect (302) to the original URL if found, or 404 if not found
  3. Get User URLs: Accept GET requests to list URLs created by a user

    • Path: /user/:username
    • Extracts the username from the path (handles URL-encoded usernames)
    • Response: { "username": "john", "urls": [{"short": "abc123", "url": "..."}] } with status 200
    • Returns empty array if user has no URLs
  4. Get URL Details: Accept GET requests with optional code parameter

    • Path: /details/:username/:code?
    • If code is provided, returns detailed info for that URL: { "short": "abc123", "url": "...", "clicks": 5 }
    • If code is not provided, returns summary: { "username": "john", "totalUrls": 3, "totalClicks": 15 }
    • Both username and code should be URL decoded if present

Implementation

@generates

For the purposes of this exercise:

  • Store data in memory using simple objects/maps
  • Generate short codes as random 6-character strings
  • Track click counts each time a redirect occurs
  • Associate each shortened URL with the username who created it

API

// Create and configure the Koa application with all routes
function createApp() {
  // Returns configured Koa app instance
}

module.exports = { createApp };

Tests

Create Short URL

  • POST to /shorten with {"url": "https://example.com", "username": "john"} returns status 201 with {"short": "..."} @test

Redirect to Original URL

  • GET to /r/abc123 (existing code) redirects with status 302 to the original URL and increments click count @test
  • GET to /r/missing (non-existent code) returns status 404 @test

Get User URLs

  • GET to /user/john returns status 200 with array of URLs created by user "john" @test
  • GET to /user/jane%20doe (URL-encoded username with space) correctly decodes to "jane doe" and returns their URLs @test

Get URL Details with Optional Parameter

  • GET to /details/john/abc123 returns status 200 with detailed info including click count for that specific URL @test
  • GET to /details/john (without code parameter) returns status 200 with summary statistics for user "john" @test
  • GET to /details/alice%20smith/xyz789 correctly decodes username "alice smith" and code "xyz789" @test

Dependencies { .dependencies }

koa { .dependency }

Provides the web application framework.

koa-route { .dependency }

Provides routing middleware with path parameter support.

koa-bodyparser { .dependency }

Provides request body parsing for POST requests.