This is a proof of concept Ruby On Rails app that utilizes Zype to fetch and display videos from a given content creator.
To see this project running visit https://my-vids.herokuapp.com/. Use any of the following credentials to access the system:
User with subscriptions
email: test@test.com
password: password
User without subscriptions:
email: test2@test.com
password: password
Disclaimer: Give the page some time to load. It's using the free version of heroku which puts the server to sleep after some time of inactivity. So it may need to spin it back up.
- zype-gem: Used to perform some of the API calls needed to Zype servers (source).
- better_settings: Used as a store of application settings (source).
- pry: Used for development purposes. Allows a better debugging & console experience (source).
- tailwindcss: Utility first css framework used to build the UI components. Allows fast prototyping. (source).
You'll need to copy and rename the included config/development.yml.example
file with config/development.yml
and fill in all the zype credentials.
You'll need to add the following environment variables to your server:
- ZYPE_API_KEY : Zype's api key
- ZYPE_APP_KEY : Zype's app key
- ZYPE_CLIENT_ID : Zype's client id
- ZYPE_CLIENT_SECRET : Zype's client secret
You can get these from Zype's admin tool.
My Vids leverages the well known MVC paradigm for its architecture. Besides this, some design patterns were implemented in order to bring calrity, maintenability and extensibility to the code.
1. Architectural diagram
The singleton pattern was used for the API client wrappers of the Zype gem. The zype gem instantiates a new client every time a request needs to be done. This is not optimal as in the long term, it will consume unnecessary memory. Given the nature of the API client, these can be wrapped withing a singleton object and avoid that excess of memory consumption. You can find one of the Zype singleton wrappers here.
Besides this usage, the singleton pattern was used to keep an instance of the current oauth session within the request lifecycle. For this, the Rails ActiveSupport::CurrentAttributes
class was leveraged (rails current attributes).
The decorator pattern was used to decorate videos when displaying them to the user. This is a thin wrapper on top of the video model that allows to expose to the views only the properties they need. You can find the video decorator here.
The presenter pattern was used to manage the presentation of the videos library. We want to paginate the list so a presenter is a good and abstract way of managing this pagination. You can find the library presenter here.
The adapter pattern was used to interface the data store. With a dsl source_from
declared in the models we are able to determine which data source is used for each model. In this demo, only Zype wrappers were implemented and used, but this can be changed for any other implementation that fulfills the interface contract.
Zype sessions last for 7 days. However, the requirements are that we need to make sessions to last 14 days. This means that we need to refresh the token granted by Zype's Oauth mechanism before it expires so that we can keep the session alive for the required time. In order to do so, we keep track of 2 expiration dates : Zype's (7 days) and MyVids (14 days). This allows us to refresh Zype's token one day before its expiration and leave the session expiration mechanism to MyVids.
For this, an OauthSession
model is present as part of the models structure. This model inherits all the attributes from zype's oauth authentication response. Besides that, the attributes of this model get persisted to the web session so that user's can stay logged in for the requested 14 days.
In order to save requests to the Zype API and bring a performance boost to the user experience we leveraged rails caching for the videos list and the video details page.
For now, we only have rspec testing for the project. To run the tests:
$ bundle exec rspec
We also have code coverage in place. So after running the above command, you can run this one:
open coverage/index.html
...to see the resulting code coverage.
- Add UI tests (integration tests) using capybara / selenium.
- Implement the "Subscribe" functionality.