DEV Community

Cover image for Did we just build a Netflix clone with Appwrite?
Matej Bačo for Appwrite

Posted on • Updated on

Did we just build a Netflix clone with Appwrite?

Image description

Welcome to the beginning of our 3 part series where we build a fully functional Netflix clone we like to call, Almost Netflix! Almost Netflix is a movie streaming app just like Netflix, but completely open source and built with technologies you love! We'll be using Appwrite to handle all the backend functionality and walk you through the process of creating the frontend in Web, Flutter, Android and iOS.

Stay tuned, as we will be continuing this series in future Appwrite releases and improving our demo step by step. Today's blog post is a setup to prepare you for what's to come tomorrow. 😉

Before jumping into the frontend, we need to prepare an Appwrite instance. This post will guide you through the installation of Appwrite, project setup, database preparation, and data insertion.

🤔 What is Appwrite ?
Appwrite is open source backend-as-a-service that abstracts all the complexity involved in building a modern application by providing you with a set of REST APIs for your core backend needs. Appwrite handles user authentication and authorization, databases, file storage, cloud functions, webhooks and much more! If there is anything missing, you can extend Appwrite using your favourite backend language.

🤖 Appwrite installation

Appwrite runs its services using a Docker infrastructure, so to install Appwrite, we will need Docker up and running on our machine. We will be running this project on a $10 DigitalOcean droplet with the Linux operating system. On Linux, we can installation Docker using the following command:

curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh
Enter fullscreen mode Exit fullscreen mode

You can skip this step if you have Docker already installed on your machine. To check that, you can run the docker --version, and if this command does not fail, you have Docker already installed.

With Docker installed, we can continue to install Appwrite. Installing Appwrite on any platform is as simple as running a single docker command in the terminal or command prompt. The command is tiny-bit different for each platform, so make sure to use the correct one from our installation docs. We are using the operating system Linux, so we use the insulation script:

docker run -it --rm \
    --volume /var/run/docker.sock:/var/run/docker.sock \
    --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
    --entrypoint="install" \
    appwrite/appwrite:0.12.0
Enter fullscreen mode Exit fullscreen mode

Make sure you use the latest Appwrite version to access all the cool features we are releasing.

Just like that ✨ we now have Appwrite installed on our machine, and when we enter the IP address into our browser, we should see Appwrite's sign-up page.

Signup page

If you are running Docker on your computer, you can use the word localhost instead of the IP address. Throughout this tutorial, we will use the domain demo.appwrite.io to reference our server running Appwrite.

🛠️ New Appwrite project

We are on the sign-up page already, so let's make an account, shall we? This process is pretty straightforward. Enter your account information and click Sign Up. Once we create the account, the website will redirect us to a dashboard where we can see a list of our projects - an empty list.

Projects list

To interact with Appwrite, we need to create a project. By clicking on the Create Project button, we open a modal where we can set the project's name and ID. Let's set the name to Almost Netflix and ID to almostNetflix.

ID is auto-generated by default, but you can click on the edit icon to allow any custom string in this field. You can learn more about this process in our custom IDs article.

New project modal

The project is created within a few seconds, and we are redirected to the project dashboard. There we go, another step finished! 💪

Appwrite provides many services to make app development more accessible and joyful, but we won't be needing all these services for our Almost Netflix project. Thanks to the latest Appwrite update, we can disable specific services we don't need to prevent users from (ab)using them.

To disable a service, click Settings at the bottom of the sidebar. In there, we switch to the Services tab, and by clicking on toggles of Locale, Health, Teams and Functions, we disable these services.

Settings services page

Perfect, services configured 👌 There's one more security feature we can enable! This time, let's click Users in the left menu and switch to the Settings tab. In this view, we can see all authentication methods allowed by Appwrite. We will only use email/password to disable the rest.

Users settings page

Finally, we are satisfied with our project setup. Let's continue by setting up the services we will be using. Thankfully, Almost Netflix only requires one service - database.

🗄 Databases, collections, attributes, and indexes

Appwrite database consists of collections. A collection is a group of multiple documents that share the same structure and potentially the same permissions. A document is a simple key-value stored in a JSON format which can also have its own permissions. Every key in a document is called an attribute, and we can configure it to a specific type, maximum length, or default value. Finally, we have indexes to optimize specific filters and sort queries.

Now that we understand the terms and know what we need to configure for every collection, let's see what collections we will need. For the sake of simplicity, we will store all movie's data in one movies collection, without any relations. Alongside that, we want to support watchlists so that we will have one collection for that. Let's see how we can configure these two collections.

The process is explained step-by-step in the Appwrite console, but you can also do this programmatically! 🤩 If you want to use a programmatic setup, you can skip a few following sections and start reading from Programming setup section.

Movies collection

We start by clicking on Database in the sidebar. We should see an empty database without any collections, so let's make one! We click on Add collection, set name to Movies and Collection ID to movies.

New movies collection

After creating the collection, we will be redirected to the settings page of our collection. We should set up permissions here because by default, Appwrite would not allow anyone to read from our new collection. First, we need to decide if we should be using collection-level or document-level permission. Our Almost Netflix use case does not call for document specific permissions, so we'll stick to Collection Level permissions in our settings page. This option opens up some more customization and allows us to specify who can read documents in this collection and who can create new ones. We want logged-in users to see all movies, and we don't need to allow anyone to create new movies because every user is just a viewer. To write this into the Appwrite permission system, we set read permissions to role:member and keep write permissions empty. Last but not least, we click Update to apply these changes.

Movies collection settings

Perfect, permissions configured! 💪 Next step, let's configure attributes. We click on the Attributes tab to see that we don't have any attributes yet.

Movies collection attributes

We will need to add a bunch of attributes, so let's make a list with all settings:

String attributes:

key size required array
name 255 true false
description 5000 false false
thumbnailImageId 255 true false
cast 255 true true
tags 255 true true
genres 255 true true

Integer attributes:

key min max required
durationMinutes 1 1000 true
netflixReleaseDate 1 - false
releaseDate 1 - false

Float attributes:

key min max required
trendingIndex - - true

Boolean attributes:

key required
isOriginal true

Enum attributes:

key required elements
ageRestriction true AR7, AR13, AR16, AR18

When we click on Add Attribute and select the type of attribute we want to add, a modal will be opened, and we can configure data from the list above. Once configured, we click Create to create one attribute. We repeat these steps for all the attributes until we have the list complete.

Movies collection with all attributes

Woah, that took quite some time. Good thing we played with so many different types and configurations. Now we can call ourselves experts of Appwrite attributes 😎

To finish the setup of the movies collection, let's switch to the indexes tab. Again, we are presented with an empty list since we didn't add anything yet. We will need multiple indexes for different filters and sorting we will do in our application in the future, so let's prepare the list again:

key type attributes
trendingIndexDESC key trendingIndex(DESC)
isOriginalDESC key isOriginal(DESC)
durationMinutesDESC key durationMinutes(DESC)
releaseDateDESC key releaseDate(DESC)
nameFULLTEXT fulltext name(ASC)
genresFULLTEXT fulltext genres(ASC)
castFULLTEXT fulltext cast(ASC)
tagsFULLTEXT fulltext tags(ASC)

Similarly to attributes, we now click on Add Index and fill the form with information from our list. We repeat until we have all indexes added.

Movies collection with all indexes

Believe it or not, the movies collection is ready! 🥳 By making this huge collection, we learned a lot of concepts and got really confident with the Appwrite interface. Here is cookie 🍪 for your effort if you followed along this far! If you ever meet me, you can trade this for a real cookie 😉

Watchlists collection

Let's do the same for the watchlist collection, but since we already understand the process, let's speed it up a little 😏

We create a new collection with name Watchlists and ID watchlists. We keep permissions on document-level, since users should only see their documents. We add the following attributes:

String attributes:

key size required array
userId 255 true false
movieId 255 true false

Integer attributes:

key min max required
createdAt 1 - true

We also add the following indexes:

key type attributes
createdAtDESC key createdAt(DESC)
userIdASCmovieIdASC key userId(ASC), movieId(ASC)

Voilà, watchlist collection setup finished ✨ There's one final step though. We need to add documents into our collections.

🌎 Programming setup

We need to create hundreds of documents, which we don't want to do manually, of course. We also don't have any data, so we will need to use some 3rd party API... What do we do now? 🤔

Thanks to Appwrite server-side SDKs, we can pick any coding language and write a programmatic setup of Appwrite documents using it. I decided to pick JavaScript for this example because this language is easy to follow along and understand when reading, in my opinion. You can also find the complete source code of the project setup in this GitHub repository.

First, let's clone the programmatic setup GitHub repository to download all the source code. Then, let's enter the folder and install all NPM libraries needed for the script to work properly:

$ git clone https://github.com/Meldiron/almost-netflix-project-setup.git
$ cd almost-netflix-project-setup
$ npm install
Enter fullscreen mode Exit fullscreen mode

We need to set up some secrets for the script to work correctly. Let's create .env file and put this information in there:

APPWRITE_ENDPOINT=
APPWRITE_PROJECT_ID=
APPWRITE_API_KEY=
MDB_API_KEY=
Enter fullscreen mode Exit fullscreen mode
  • You can find the Appwrite endpoint and project ID in the settings of your project
  • You can create an API key in the API Keys section of your Appwrite project. You can give it all permissions to make sure it has access to all services we might need to use
  • You can get your MDB API key by signing up to TMDB. Learn more in TMDB docs.

We are set! 😎 Let's now use this script.

If you set up the database manually, you can ignore the following paragraph and command.

If you didn't follow previous sections to set up movies and watchlists collections, now it's a great time to use a programmatic setup for that. I personally prefer using a programmatic setup to create collections, attributes, and indexes. This way, I keep the setup in a file that can be pushed to version control (Git). To run the script that creates all of that, we run:

$ node src/migrations.js
Enter fullscreen mode Exit fullscreen mode

The final step is to insert documents. Thankfully, we have a script for downloading the movie list and their images from TMDB, so all we need to do is to run the script and wait until it's finished:

$ node src/seeds.js
Enter fullscreen mode Exit fullscreen mode

If everything goes well, we can see documents in our movies collections and many movie covers in our storage.

Movies collection documents

Storage with images

✨️ Conclusion

That's it! We successfully prepared our Appwrite project for Almost Netflix, and we are ready to use it in a frontend application. In the next tutorial, we'll build a Netflix Clone using Nuxt ( or Vue ) and walk you through the process of building apps with Appwrite! As always, we can't wait to see what you will build with Appwrite! You can also join our Discord server to become part of the friendly and supportive Appwrite community.

Here are some handy links and resources:

🔗 Learn more

You can use the following resources to learn more and get help regarding Appwrite and its services.

Discussion (11)

Collapse
kohsheen1234 profile image
Kohsheen Tiku

Wow! This is really detailed 👌

Collapse
tananga profile image
tananga

I hope that its just a first big project created by team :) Great to see some good tutorial. Last time I was following reactBits on youtube but it was outdated. Its really nice to see that you can build something similar to Netflix with Appwrite.

Collapse
tananga profile image
tananga

I finished this part. Not everything went smooth. I had to change a lot of things to make it run. In case of problems you can text me.

Collapse
stnguyen90 profile image
Steven

Like what?

Collapse
mirolyubovn profile image
Nikita Mirolyubov • Edited on

Migrations and seeds scripts do not execute correctly. It seems like there is a 'bucket' required, which was not indicated to setup in this tutorial.

Migration:
� Could not finish migration:
AppwriteException [Error]: Bucket not found
at Client.call (D:\Websites\almost-netflix-project-setup\node_modules\node-appwrite\lib\client.js:160:31)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Storage.listFiles (D:\Websites\almost-netflix-project-setup\node_modules\node-appwrite\lib\services\storage.js:50:16)
at async D:\Websites\almost-netflix-project-setup\src\migrations.js:87:25 {
code: 404,
response: { message: 'Bucket not found', code: 404, version: '0.13.4' }
}

Seeds:
� [1/25] Downloading +20 movies ...
AppwriteException [Error]: Bucket not found
at Client.call (D:\Websites\almost-netflix-project-setup\node_modules\node-appwrite\lib\client.js:160:31)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Storage.createFile (D:\Websites\almost-netflix-project-setup\node_modules\node-appwrite\lib\services\storage.js:97:16)
at async intiniteRequest (D:\Websites\almost-netflix-project-setup\src\seeds.js:21:15)
at async downloadMovies (D:\Websites\almost-netflix-project-setup\src\seeds.js:82:17)
at async D:\Websites\almost-netflix-project-setup\src\seeds.js:137:3 {
code: 404,
response: { message: 'Bucket not found', code: 404, version: '0.13.4' }

Collapse
tananga profile image
tananga

Great idea. Please show how to use it with Flutter in details

Collapse
meldiron profile image
Matej Bačo Author

Stay tuned, we will be releasing Flutter Almost Netflix soon 😊

Collapse
eldadfux profile image
Eldad A. Fux

Flutter version is available here: dev.to/appwrite/almost-netflix-a-n...

Collapse
tananga profile image
tananga • Edited on

I cant create Boolean attribute. Can someone help?

dev-to-uploads.s3.amazonaws.com/up...

Collapse
stnguyen90 profile image
Steven

I believe an issue has been created for this and the PR is pending merge.

Collapse
stnguyen90 profile image
Steven • Edited on