Skip to content

mgsouth/msouth-ur

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 

Repository files navigation

Requirements Note

This project was a take-home code test. I don't want to just cut-and-paste the requirements, but the ask was for a RESTful short-URI app. The user could submit URLs and get back a short-form, be redirected through the short-form, and get a list of all existing short URLs including time since creation and targets. Needed to include instructions to install, test, and run (this document). Deployment was not required.

I hadn't used Flask before, but it was part of the requestor's tech stack. It's a decent little web service framework, not too hard to pick up.

Note: I think returning an absolute time would be much preferable to returning a difference from "now", but that was the ask.

Installation & Setup, Linux or macOS:

$ git clone https://github.com/mgsouth/msouth-ur
$ cd msouth-ur
$ python3 -m venv venv
$ . venv/bin/activate
$ pip install click
$ pip install Flask

Launch the service:

$ export FLASK_ENV=development
$ python ur.py

Clear out the saved short urls:

$ rm redirs.*

Examples

The user creates URL shortcuts by sending RESTful POSTs to the server's "../redirs/" endpoint; the JSON response will have the resulting short URL (or an error). The user can then send a GET or POST to the same server, which will respond with a redirect to the desired endpoint. The user can also get a list of all existing shortcuts by doing a GET on the ".../redirs/" endpoint.

In a terminal session:

$ export FLASK_ENV=development
$ python ur.py

Now, create a short-URL. We'll use a curl POST. In a separate terminal session:

$ curl -i -d '{"long_url": "http://whatever.com"}' 'http://127.0.0.1:5000/redirs/'

=>

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 155
Server: Werkzeug/2.0.1 Python/3.6.5
Date: Fri, 16 Jul 2021 09:42:22 GMT

{
  "reason": "",
  "redir": {
    "age": 0,
    "long_url": "http://whatever.com",
    "short_url": "http://127.0.0.1:5000/C"
  },
  "status": "OK"
}

$ curl -i -d '{"long_url": "https://en.wikipedia.org/wiki/URL_shortening"}' 'http://127.0.0.1:5000/redirs/'
$ curl -i -d '{"long_url": "http://127.0.0.1:5000/redirs/"}' 'http://127.0.0.1:5000/redirs/'
$ curl -i 'http://127.0.0.1:5000/redirs/'

=>

    HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 451
    Server: Werkzeug/2.0.1 Python/3.6.5
    Date: Fri, 16 Jul 2021 09:51:24 GMT
    
    {
      "reason": "",
      "redirs": [
        {
          "age": 390,
          "long_url": "http://whatever.com",
          "short_url": "http://127.0.0.1:5000/C"
        },
        {
          "age": 369,
          "long_url": "https://en.wikipedia.org/wiki/URL_shortening",
          "short_url": "http://127.0.0.1:5000/D"
        },
        {
          "age": 243,
          "long_url": "http://127.0.0.1:5000/redirs/",
          "short_url": "http://127.0.0.1:5000/E"
        }
      ],
      "status": "OK"
    }

Now we can send a GET to the short URL, and we will be recdirected to the Wikipedia page. In the following, we need the -L so that curl will actually follow the redirect.

$ curl -i -L http://127.0.0.1:5000/D

=>

    HTTP/1.0 302 FOUND
    Content-Type: text/html; charset=utf-8
    Content-Length: 294
    Location: https://en.wikipedia.org/wiki/URL_shortening
    Server: Werkzeug/2.0.1 Python/3.6.5
    Date: Fri, 16 Jul 2021 09:52:34 GMT
    
    HTTP/2 200
    date: Thu, 15 Jul 2021 20:15:58 GMT
    vary: Accept-Encoding,Cookie,Authorization
    server: ATS/8.0.8
    x-content-type-options: nosniff
    p3p: CP="See https://en.wikipedia.org/wiki/Special:CentralAutoLogin/P3P for more info."
    content-language: en
    last-modified: Mon, 12 Jul 2021 21:28:15 GMT
    content-type: text/html; charset=UTF-8
    age: 48996
    ...

Shortened POST:

It can be a little difficult finding a short example of a site accepting a POST. So we'll be meta and use the short-URL service itself as an example. We'll set it up so that it creates a double-redirection; the first one points to another short-URL, and then following that redirection goes to the final endpoint.

$ curl -i -d '{"long_url": "http://127.0.0.1:5000/redirs/"}' 'http://127.0.0.1:5000/redirs/'

=>

"short_url": "http://127.0.0.1:5000/F"

In the next command, note there's no trailing slash after the F.

Without the --post302 curl with do a GET on the redirect rather than a POST.

$ curl -i -L --post302 -d '{"long_url": "https://news.ycombinator.com"}' 'http://127.0.0.1:5000/F'

=>

HTTP/1.0 302 FOUND
Content-Type: text/html; charset=utf-8
Content-Length: 264
Location: http://127.0.0.1:5000/redirs/
Server: Werkzeug/2.0.1 Python/3.6.5
Date: Fri, 16 Jul 2021 09:58:07 GMT

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 164
Server: Werkzeug/2.0.1 Python/3.6.5
Date: Fri, 16 Jul 2021 09:58:07 GMT

{
  "reason": "",
  "redir": {
    "age": 0,
    "long_url": "https://news.ycombinator.com",
    "short_url": "http://127.0.0.1:5000/G"
  },
  "status": "OK"
}

REST API

* Insert a long -> short redirection.

    POST <host>/redirs/
    { "long_url": <target> }

=>

    { "status": "OK",
      "reason": "",
      "redir": {
          "short_url":  <URL>,
          "long_url":   <URL>,
          "age":        <age of entry, in seconds, relative to current time>,
      }
    }

-or-

    { "status": "ERROR",
      "reason": <note describing error>,
      "redir":  null,
    }


* Get a list of all redirections.

    GET <host>/redirs/

=>

    { "status": "OK"
      "reason": "",
      "redirs": [
          {
              "short_url":  <URL>,
              "long_url":   <URL>,
              "age":        <age of entry, in seconds, relative to current time>,
          }
          ...
      ]
    }

About

URL-shortener excercise

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages