Code Monkey home page Code Monkey logo

dazn-test's Introduction

dazn-test

tech test for dazn

Test

Build a service in your preferred language that exposes an API which can be consumed from any client. This service must check how many video streams a given user is watching and prevent a user watching more than 3 video streams concurrently.

My Approach

The challenge is quite interesting, and it is something I never done before. To start with I was thinking to implement something more like "IP related download restriction", like some download mirror website do, but then I realized that the "user" term was used. So I decided to implement a fake DAZN website with limited login capabilities, in order to identify the user browser side.

I decided to build a catalog on the frontend system that is going to use the same small backend to allow a user to browse and choose what to watch, the same backend will identify whether the user is already streaming something and block him if it is already going over a certain threshold/limit.

Repository guide

I decided to go with a mono-repo approach, both FE and BE will be in the same repository in two different sub folders.

Backend

I decided to use a small boilerplate I use for some of my projects, written in micro. after running the install script npm install, to run it you can use either the docker-compose file.

docker-compose up -d

run it in dev mode locally (with auto reload on file change)

npm run dev

Endpoints

ping

GET /ping

this endpoint is needed just to check if the API is actually running correctly

-> % http get localhost:3001/ping        
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 18
Content-Type: application/json; charset=utf-8
Date: Sun, 08 Dec 2019 12:50:09 GMT

{
    "pong": true
}

user

POST /login

this endpoint is a fake login facility, it will be used to identify the user who is trying to stream the video using a JWT bearer token. params: username, password (those are specified in the env file)

-> % http post localhost:3001/login <<< '{"username": "vince", "password":"password"}'
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 169
Content-Type: application/json; charset=utf-8
Date: Sun, 08 Dec 2019 14:08:11 GMT

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiaVN4ODduejIifSwiZXhwaXJlcyI6IjE1NzU4MTQwOTEzNjAwIn0.2QCyoEJ3iYdkQxI54w6L2GpiWvhULSPBavo_NDR6HsY"
}

GET /me

this endpoint is used to get the user info from JWT token and to check the validity of the same, this will be used on the FE to verify whether the user is still logged in if it is returning after closing the browser.

-> % http get localhost:3001/me Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiaVN4ODduejIifSwiZXhwaXJlcyI6IjE1NzU4MTQwOTEzNjAwIn0.2QCyoEJ3iYdkQxI54w6L2GpiWvhULSPBavo_NDR6HsY
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 83
Content-Type: application/json; charset=utf-8
Date: Sun, 08 Dec 2019 14:12:07 GMT

{
    "id": "iSx87nz2",
    "maxStreams": 3,
    "plan": "basic",
    "username": "vince"
}

GET /me/slots

this endpoint will print which slots are you currently watching, it was used for debug mostly, but could be useful to show a warning on the main website for example.

-> % http get localhost:3001/me/slots Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiaVN4ODduejIifSwiZXhwaXJlcyI6IjE1NzU5MDA1MDMzNjAwIn0.qUSUJkyRo53WlWARgVRtSBKBmOkdiM9SnSRThFJ8VjI
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 33
Content-Type: application/json; charset=utf-8
Date: Mon, 09 Dec 2019 14:43:53 GMT

[
    "37cx7fcvc",
    "Int3RM3rd4"
]

catalog

GET /catalog/live

this endpoint is used to get a list of live events. (for the purpose of this test those are mocked and loaded form a json file)

-> % http get localhost:3001/catalog/live      
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 586
Content-Type: application/json; charset=utf-8
Date: Sun, 08 Dec 2019 14:30:37 GMT

[
    {
        "img": "https://vikkio.me/dazn/img/baseball.jpg",
        "label": "NYC vs Denver",
        "sport": "baseball",
        "streamId": "AXsu8222"
    },
    {
...

GET /catalog/stream/:streamId

this endpoint is used to get the stream url given a stream id, this will perform the check on whether the current logged in user can stream that resource or not. (For the scope of this test this will be a simple file url, which the FE app will mount inside an <video> tag). If you are exceeding your stream quota:

-> % http get localhost:3001/catalog/stream/S0m3IDStR34m Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiaVN4ODduejIifSwiZXhwaXJlcyI6IjE1NzU4MTQwOTEzNjAwIn0.2QCyoEJ3iYdkQxI54w6L2GpiWvhULSPBavo_NDR6HsY
HTTP/1.1 403 Forbidden
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 94
Content-Type: application/json; charset=utf-8
Date: Sun, 08 Dec 2019 14:19:22 GMT

{
    "message": "Your current plan (basic) allows you only to stream 3 videos concurrently."
}

If you are not exceeding your quota but your stream id does not exist:

-> % http get localhost:3001/catalog/stream/NonExist1ng1d Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiaVN4ODduejIifSwiZXhwaXJlcyI6IjE1NzU4MTQwOTEzNjAwIn0.2QCyoEJ3iYdkQxI54w6L2GpiWvhULSPBavo_NDR6HsY
HTTP/1.1 404 Not Found
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 51
Content-Type: application/json; charset=utf-8
Date: Sun, 08 Dec 2019 14:27:21 GMT

{
    "message": "Stream not found 'NonExist1ng1d'"
}

if you are allow to stream it:

-> % http get localhost:3001/catalog/stream/37cx7fcvc Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiaVN4ODduejIifSwiZXhwaXJlcyI6IjE1NzU4MTQwOTEzNjAwIn0.2QCyoEJ3iYdkQxI54w6L2GpiWvhULSPBavo_NDR6HsY
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 47
Content-Type: application/json; charset=utf-8
Date: Sun, 08 Dec 2019 14:28:02 GMT

{
    "fileUrl": "https://some.com/fileurl.mp4"
}

DELETE /catalog/stream/:streamId/slot

this endpoint is used to release a streaming slot, and it will be called by the stream View if you leave the page or if you unload the document. This second part seems not working properly, but I am sure you get the gist of it.

-> % http delete localhost:3001/catalog/stream/suc872X22/slot Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiaVN4ODduejIifSwiZXhwaXJlcyI6IjE1NzU5MDA1MDMzNjAwIn0.qUSUJkyRo53WlWARgVRtSBKBmOkdiM9SnSRThFJ8VjI
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 33
Content-Type: application/json; charset=utf-8
Date: Mon, 09 Dec 2019 14:43:53 GMT

{
    "status": "ok"
}

Frontend

I decided to go with a simple SPA using Create-React-app for the frontend part.

How to

To run the FE part, after npm install you can just

npm start

and it will startup your default browser at :3000

You can at any point build the app and upload the assets to any static hosting and run them in your browser from there.

dazn-test's People

Contributors

vikkio88 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.