Challenge Overview
This challenge will implement some simple REST services that will build the base for a set of web applications that will eventually run on an embedded TV device for our customer.
The application will show a list of video assets scraped off of websites, like foxnews.com, cnn.com, youtube, or hgtv.com as examples. The video assets will be aggregated and displayed to the user for playback on their TV.
We are going to target:
* Node.js
* Heroku
* Redis or another in-memory data store
* JSON
* Swagger for API documentation
Data model
The data model will be fairly generic. In the future, we will run challenges to build data collectors that look at the video asset data on a given site and then translate that data into generic assets that we house in our data store in our web app.
Video Asset:
* Category (string)
* Title (string)
* Description (string or text)
* Publish Date (date/time) (optional)
* Run length (integer, representing seconds) (optional)
* Thumbnail image (url) (optional)
* Video URL (url)
* Provider (HGTV, Fox News, YouTube, ABC, etc...) (string) (optional)
* Expiration date (not parsed, but set by the system) (date/time) (set by system)
* Asset ID (guid) (set by system)
REST API
The REST API will allow for adding video assets into the data store (called "ingesting"), deleting assets from the data store, editing assets in the data store, and pulling feeds of video assets based on sort parameters. The REST API will expect JSON in the POSTs and will return JSON in the GETs. As we add onto the web app, we will return HTML or JSON for certain endpoints, like the feeds, depending on the content-type given in the header. "application/json" will return JSON, but "application/html" might return a web page instead.
Adding video asset:
Adding a video asset is done by a POST to /videos/. The video asset will expect to be filled with the data detailed in the data model. Anything not marked optional is required.
When a new video is added, we want to go through and remove any videos that have an expiration date before the current date/time.
For the expiration date, this should be set by taking the current time and adding in a configurable offset to the date, like 48 hours.
The asset ID will be a GUID generated by our Node.js app for each record inserted.
Deleting a video asset:
Deleting a video asset will be done by a DELETE request to /videos/{asset ID}
Updating a video asset:
Updating a video asset will be done by a PUT request to /videos/{asset ID}. The request should be JSON representing the updated record, and the caller should be able to update the expiration date explicitly. The expiration date should not be calculated by the system on this update call.
Retrieving video assets:
A GET request to /videos/ will return a list of all available video assets in a JSON array, sorted by publish date descending.
Searching video assets:
A GET request to /videos/search/{search term} will return a list of video assets that have title or description text that matches the given search term. If a search term is multiple words, we will search for each word individually, and the search comparison will be case insensitive. If multiple words are used in the search term, the results will be sorted by search match in this order:
1. Records that match the search term exactly
2. Records that have all the words of the search term in them, but maybe not in the given search order
3. Records that have one or more of the words of the search term in them
In each of these categories, the records will be sorted by publish date descending
Filtering:
In addition to retrieving all videos and searching, we want to have the ability to filter search and regular video feed responses by the following parameters:
* Category
* Provider
* Publish date
We can have these as URL parameters on the /videos/search and /video GET calls
* "category" would be a comma-delimited string of the categories of videos to return in the results
* "provider" would be a comma-delimited string of the providers of videos to return in the results
* "publishedAfter" would be a date that would filter out any records with a publish date *before* the parameter value
* "publishedBefore" would be a date that would filter out any records with a publish date *after* the parameter value
The string comparisons for category and provider should be case insensitive.
Data store
We want to keep the data store as lean as possible. GrapheneDB / Neo4j is easily supported on Heroku, but you are free to offer suggestions as to other data stores, as long as the data store implementation runs on Heroku as an add-on. Please get confirmation from the copilot if you would like to target a different data store.
Heroku deployment
The final application will be developed and will "live" in Heroku until the customer decides to move it to production. Please make sure your submission is easily deployed to Heroku and that your deployment guide makes sure to document any add-ons or non-standard steps that are necessary to publish the code to Heroku. Please target the latest supported version of Node.js on Heroku and the latest version of any add-ons.
Tests
Unit tests are required for this challenge. Please provide basic unit tests to cover the the API. The implementation is at your discretion, but we have used Chai in the past for other Node.js libraries and services.
Swagger docs
As part of your submission, Swagger documentation for the API you create is required:
http://swagger.io/
Documentation
For this challenge, you can submit a deployment and verification guide in Markdown format. No video is required. Please also make sure to submit a Swagger doc that matches your API.
Additional features
For additional features consideration, please consider:
* Extra unit tests or code coverage tools
* Extra validation or testing features
* Data storage tweaks or ideas that can lead to a very fast implementation
Keep in mind the feed is not going to change constantly - it will be relatively static, but the ingestion will happen via scheduled jobs on a semi-regular basis (think 30-60 minutes)
The application will show a list of video assets scraped off of websites, like foxnews.com, cnn.com, youtube, or hgtv.com as examples. The video assets will be aggregated and displayed to the user for playback on their TV.
We are going to target:
* Node.js
* Heroku
* Redis or another in-memory data store
* JSON
* Swagger for API documentation
Data model
The data model will be fairly generic. In the future, we will run challenges to build data collectors that look at the video asset data on a given site and then translate that data into generic assets that we house in our data store in our web app.
Video Asset:
* Category (string)
* Title (string)
* Description (string or text)
* Publish Date (date/time) (optional)
* Run length (integer, representing seconds) (optional)
* Thumbnail image (url) (optional)
* Video URL (url)
* Provider (HGTV, Fox News, YouTube, ABC, etc...) (string) (optional)
* Expiration date (not parsed, but set by the system) (date/time) (set by system)
* Asset ID (guid) (set by system)
REST API
The REST API will allow for adding video assets into the data store (called "ingesting"), deleting assets from the data store, editing assets in the data store, and pulling feeds of video assets based on sort parameters. The REST API will expect JSON in the POSTs and will return JSON in the GETs. As we add onto the web app, we will return HTML or JSON for certain endpoints, like the feeds, depending on the content-type given in the header. "application/json" will return JSON, but "application/html" might return a web page instead.
Adding video asset:
Adding a video asset is done by a POST to /videos/. The video asset will expect to be filled with the data detailed in the data model. Anything not marked optional is required.
When a new video is added, we want to go through and remove any videos that have an expiration date before the current date/time.
For the expiration date, this should be set by taking the current time and adding in a configurable offset to the date, like 48 hours.
The asset ID will be a GUID generated by our Node.js app for each record inserted.
Deleting a video asset:
Deleting a video asset will be done by a DELETE request to /videos/{asset ID}
Updating a video asset:
Updating a video asset will be done by a PUT request to /videos/{asset ID}. The request should be JSON representing the updated record, and the caller should be able to update the expiration date explicitly. The expiration date should not be calculated by the system on this update call.
Retrieving video assets:
A GET request to /videos/ will return a list of all available video assets in a JSON array, sorted by publish date descending.
Searching video assets:
A GET request to /videos/search/{search term} will return a list of video assets that have title or description text that matches the given search term. If a search term is multiple words, we will search for each word individually, and the search comparison will be case insensitive. If multiple words are used in the search term, the results will be sorted by search match in this order:
1. Records that match the search term exactly
2. Records that have all the words of the search term in them, but maybe not in the given search order
3. Records that have one or more of the words of the search term in them
In each of these categories, the records will be sorted by publish date descending
Filtering:
In addition to retrieving all videos and searching, we want to have the ability to filter search and regular video feed responses by the following parameters:
* Category
* Provider
* Publish date
We can have these as URL parameters on the /videos/search and /video GET calls
* "category" would be a comma-delimited string of the categories of videos to return in the results
* "provider" would be a comma-delimited string of the providers of videos to return in the results
* "publishedAfter" would be a date that would filter out any records with a publish date *before* the parameter value
* "publishedBefore" would be a date that would filter out any records with a publish date *after* the parameter value
The string comparisons for category and provider should be case insensitive.
Data store
We want to keep the data store as lean as possible. GrapheneDB / Neo4j is easily supported on Heroku, but you are free to offer suggestions as to other data stores, as long as the data store implementation runs on Heroku as an add-on. Please get confirmation from the copilot if you would like to target a different data store.
Heroku deployment
The final application will be developed and will "live" in Heroku until the customer decides to move it to production. Please make sure your submission is easily deployed to Heroku and that your deployment guide makes sure to document any add-ons or non-standard steps that are necessary to publish the code to Heroku. Please target the latest supported version of Node.js on Heroku and the latest version of any add-ons.
Tests
Unit tests are required for this challenge. Please provide basic unit tests to cover the the API. The implementation is at your discretion, but we have used Chai in the past for other Node.js libraries and services.
Swagger docs
As part of your submission, Swagger documentation for the API you create is required:
http://swagger.io/
Documentation
For this challenge, you can submit a deployment and verification guide in Markdown format. No video is required. Please also make sure to submit a Swagger doc that matches your API.
Additional features
For additional features consideration, please consider:
* Extra unit tests or code coverage tools
* Extra validation or testing features
* Data storage tweaks or ideas that can lead to a very fast implementation
Keep in mind the feed is not going to change constantly - it will be relatively static, but the ingestion will happen via scheduled jobs on a semi-regular basis (think 30-60 minutes)