Let's Checkout... AppWrite
AppWrite is a secure open source backend server for Web, Mobile and Flutter developers. And we are gonna check it out in this video.
What is AppWrite
AppWrite is an Open Source backend as a service platform, similar to Firebase and Supabase. What makes it different from those services is that it only has self-hosted version at the time of making this video, and the cloud version that you can pay for is coming soon.
Supabase also has a self-hosted version, but from what I understand it’s kind of a pain to setup. I didn’t try it so maybe take this with a grain of salt, and be sure to correct me in the comments.
AppWrite on the other hand is super easy to setup locally using Docker, and that is not all, it also has one click install on Digital Ocean, which I’m going to show you in this video.
One more big difference when comparing it to Supabase is that AppWrite wraps around NoSQL database while Subabase is connected to Postgres database. So if you are choosing between these two, keep that in mind, because if you need a relational database, AppWrite is not going to be for you.
At the time of making this video AppWrite is in version 0.14.2 but it has a great feature set comparable to Supabase.
- It has a database
- It can handle your storage using Buckets
- It has users section which is actually authentication with more than twenty providers
- It has cloud functions out of the box with more than 15 runtimes
- It has a great set of SDKs for the most popular languages and platforms including Flutter, Android, iOS, Kotlin, Python, PHP and of course JavaScript which I’m going to show you in this video.
- SDK is super simple to use
- And you can also install one instance of AppWrite but have it run multiple projects
You would usually use AppWrite to create your own backend. Because, even if AppWrite looks like a CMS on the first glance, and you can add data to your Database from its admin area, it’s still miles away from something like Directus or WordPress which have a lot of components that can make editing actual content and data of your app enjoyable experience.
AppWrite is just going to serve as a backend to your backend and it will allow you to easily read and write data, authenticate users and provide you with Cloud functions and storage system. But not much else. So keep that in mind… and you know… read the docs.
In this video I’m going to show you how to setup AppWrite locally first, but for the demo we are actually going to be using Digital Oceans one click setup for AppWrite.
I’m going to show you how to quickly get the data from the database, how to register and login users, and also how to create protected pages on your site which only authenticated users can access.
This is going to be super simple using AppWrites JavaScript SDK.
For the frontend I will of course be using Next.js. But you can use any framework you like.
Local Install
To get started locally first install Docker Desktop on your machine if you don’t already have it.
Once you have it installed, just copy the command from the modal you get when you click on “Get started” button on AppWrites site.
Paste that command in your terminal, wait a bit, answer a few questions, and you are good to go.
Visit http://localhost
in your browser and you should be greeted with AppWrites account creation screen.
Digital Ocean install
However for this demo I’m going to be using Digital Oceans one-click install. If you wanna follow along with me, you can sign up using my affiliate link and get $100 of credit for 60 days, so you can play with AppWrite there or with any other technology you like, the link will be in the description bellow.
And I think this is the easiest way to get started with AppWrite, but local setup is just fine if you wanna just test it out locally.
Once you sign up to Digital Ocean Account you can click on create button to create a droplet.
Then go to Marketplace and search for Appwrite, click on it. Choose any droplet you like, but I suggest you don’t go for the cheapest one. I will choose the one for $12 per month with premium Intel chip.
After that you can choose region for your datacenter. Choose something closest to you.
Since I’m in Croatia I will choose the one in Frankfurt.
I will choose SSH key as my authentication method, but you can choose root password if you don’t know how to use SSH or you don’t wanna bother with it.
Change hostname to something like AppWrite and then click Create Droplet.
Now we wait for a minute or two for our droplet to be created.
Once this is done you will see AppWrite logo and “Get started” text, click on that. And then on “Quick access to AppWrite”.
If you get “Site can’t be reached” error, don’t worry. Wait for a few more minutes and try to refresh the page. This is because AppWrite needs a few minutes to get set up on your Droplet.
When you refresh the page after a few minutes you should be greeted with the Sign Up page, on which you can create your admin user.
Add your data and click Sign Up. And that is it, we are ready to start creating our app.
Create simple project
First of all let’s change the theme.
Ok, better.
Now let’s create our first project. Name your project however you want, I will call mine “Movie Database”.
On this page you can see all the features that AppWrite comes with. Database, Storage, Users and Functions.
Users also contain authentication methods you can use with AppWrite. We are going to authenticate with user name and password in this video.
Let’s go to the database and create our first Collection. I will name mine “Movies”.
On this page you can set read and write permissions either on “Collection level” or if you wan’t more granular control on “Document level”.
I’m going to set Read Access to be role:all
so that every one can read our documents.
Documents are items in your database and they are made up of Attributes. If you now go to documents, you will actually see “Create Attribute” instead of “Create Document” button. Because you need at least one attribute for your Documents.
So let’s create some. There are a few attribute types, String, Integer, Boolean and so on. All the usual suspects.
Let’s add a String attribute, and give it and ID of title, the size is going to be 100. Now click “Create” button.
Now I will add one more, this time of type integer. And I’m going to call this one “year”. So our movies are going to have a title and a year.
We have two Attributes now, so that means that we can create a few Documents.
So the title of my Document will be “Big Lebowski” and the year is going to be 1998. Note that under permissions you can add read and write access, for that specific document. So that is cool.
Let’s add a few more Movies, or you know… Documents.
Ok, so now we got our first project set up, now we just need to click on “Home” link and then click “Add Platform” so that we can use AppWrite SDK in our Next.js app. Click “Add Platform” and choose “New web app”.
For the name we can just write “Movie Database” again. For host name you actually need to add URL to your site that is going to be using AppWrites API.
We are just going to add a wildcard for now, so that we can access it from anywhere, including our localhost.
In production of course you wanna restrict access so that only your web app can use it.
And with that we are done with our demo setup, of AppWrite. Let’s now quickly create a simple web app that that will get our Movies (or Documents) and allow us to authenticate our users.
Next.js setup
I’m using Next.js for this demo with only Tailwind installed. To create the same setup you can just install Next with yarn create next-app name-of-your-project
and then follow simple instructions on Tailwind page.
If you want to automatically install Next and Tailwind together with just one line you can run yarn create next-app --example with-tailwindcss name-of-your-project
but be aware that this is going to install Next.js with TypeScript support. So if you don’t want to use TypeScript go with the first example.
Install AppWrite SDK
To install AppWrite SDK for web just run yarn add appwrite
in the root of your app.
But we are also going to add uuid
package, because we are going to need it later on.
Nice.
Now let’s just add .env.local
to the root of our project and add ENDPOINT, PROJECT_ID and COLLECTION_ID.
ENDPOINT is the url of your site plus /v1
.
You can find PROJECT_ID by going Home and then clicking Settings. Here you can copy your Project ID.
For the COLLECTION_ID go to the Database click on Movies and then Settings.
You can copy the Collection ID from here.
Now just copy and paste all those variables and prefix them with NEXT_PUBLIC_
so that we have access to them in the browser.
And that is it. We can start developing.
Getting the Documents (Movies)
In index.jsx
import Appwrite
so that we can use the SDK.
And after that we are going to get our Movies in getServerSideProps
, so on the server-side. But you can also do it the same way on client side. There is no need for fetch
, axios
and so on. SDK is going to handle all of that for us.
First we new up Appwrite
and just call it sdk
.
Then we define our end point and project from the data that we saved in .env.local
. We are going to use these two lines before everything we do with AppWrite SDK.
For the purposes of this demo I’m going to always add them, but for the project in production it would make more sense to create a React hook for that or some function that you can reuse.
Then we wanna list documents from our Collection. And as you can see, AppWrite SDK is very simple and intuitive, you just say listDocuments
and pass in the collection you want to list the documents from, and then wait for the response.
If we get the response we return it, otherwise we return an error.
We await for the response to resolve, and pass it to the props of our component.
Now we just pass movies
prop to our component, and then we can map over it and display the title and the year of the movie. I also added a Link
component that is going to link our movie to the URL of /movies/id-of-the-movie
which is going to show detailed view for all of our movies.
And that is it. If we take a look at our homepage, we should see a list of movies.
Nice.
Getting a single document (Movie)
To link our movie to the movie details page, we first create movies
folder under pages and in it I will create [id].jsx
file since we are going to get our movie by ID.
In getServerSideProps
we are going to pass in ctx
or context. And then we are going to use that context to get the id
of the movie that we wanna show.
After that we just initialise AppWrite SDK like we did on the index page.
To get the document, it’s very simple, you can just use getDocument
method, pass in Collection ID from .env.local
and the id
of the movie that we got from context.
Now we just wait for the response, and then send it to our props
property.
We receive that property in our component through props, and then just add the movie.title
to the <title>
tag in Head
component, and also display the title of the movie on the page.
And below it, we can display the year in a <span>
tag.
Now on our Homepage when we click the movie, we should go to the URL /movies/id-of-the-movie
and we should see the title and the year of that movie.
Details page of the movie… Done!
Register users
To register users first we need to create register.jsx
page. Import Appwrite
of course, and also import uuid
because we are going to need that to generate and ID for the user.
On this page we also have a simple form with an e-mail and password fields, and of course a button for submitting the form. At the bottom we are going to display the errors if we get any.
Nice thing about AppWrite is that it has server-side validation that you can use on your frontend. I will show you how in a few moments.
And don’t worry, all of this code is going to be available for you on Github, the link will be in the description below.
And of course our form has a submit method that is going to call handleSubmit
method when the user clicks the button.
Now let’s create a state for handling our errors.
After that we are of course going to initialise AppWrite SDK.
Now just create handleSubmit
method. In it we first preventDefault
of course, so that our page doesn’t reload.
And then we just use SDK method account.create
and in it pass in the ID generated by UUID, email and password from our form.
Then we just console log the response
but if we get an error we wanna setError
with the method from useState
hook.
That error is going to be displayed below the form.
And that is it, let’s test it out.
Go to the /register
route and try to write some random string in the e-mail field.
You will get “Invalid email: Value must be a valid email address” error.
Ok now add an email address like “[email protected]” but add just three characters for the password. Now you will get “Invalid password: Password must be at least 8 characters” .
So as you can see validation works.
Let’s now add a password that is at least 8 characters long and click “Sign Up”.
Nothing will happen, since we didn’t code anything to happen. But if we go to our admin area under users, we should see our new user.
Click on the user and add a name for it, since we didn’t send the Name in our request, and then click Update.
We registered our first user, now we can create a Login page.
Login users
To login users we pretty much do the same thing like we did when registering users.
Create login.jsx
page, in it we have almost the same setup with the form, handeling submit and we are using useState
to display errors. And I’m also going to initialise Next router so that we can send the user to the User Area if the login is successful.
In handleSubmit
we need to use account.createSession
method to which we will send an e-mail and password from the form.
And this is going to create a session for our user.
Now if we get the response with the userId
we wanna push the user to the user area page. Otherwise, we wanna set the error and display it, just like we did on the register page.
Let’s test this out.
Try to login with invalid credentials, and you will get “Invalid credentials” error.
But if you use the right credentials of the user we just created, we should be redirected to the user area page. Of course this is going to produce an error, because there is no /user-area
page yet.
Let’s create one now.
User area
First of course let’s create user-area.jsx
inside our pages
folder.
In it I will just add the text that is going to say Hello, and the name of the user.
Then I’ll just add a simple “This is an authenticated page.” paragraph.
And bellow that I will add a logout button, that is going to trigger logout
method once somebody clicks on it.
Ok, now we need to add some logic to make all of this work.
I’m going to set two states - first is going to be user
, in it we will set the users data, so that we can display it and after that I will set isAuthenticated
state, so that we can check if the user is authenticated.
Also we wanna initialise Next router so that we can redirect users that are not authenticated.
After that we initialise Appwrite
of course, like in all the previous examples.
Now I want to get the session for the current user, and wait for the response. If we get current
property in the response, then we wanna set authenticated to true.
But if we get error.code
with the code of 401
which is the code for unauthorised request, we are going to push the user to the login page.
After that we are going to use useEffect
which is going to depend on the isAuthenticated
state, and when that state changes we are going to to try to get the account details for the current user, with account.get()
method.
We don’t need to send anything to that method because AppWrite SDK is going to try to get the data for the user from the session we created when logging in.
Now we wait for the response, and if we get it we set user
state to be that response.
And we can just console log out any errors we get.
In the logout
method we use account.deleteSessions()
method to delete all users sessions.
And then we just push the user to the homepage if the request was successful, otherwise we console log any errors we may get.
Lastly we are checking if the user is not authenticated, and returning blank page if that is the case.
We do this because otherwise we would get flash of the page that the user is not supposed to see if they are not authenticated until all the other logic is run, which is just a fraction of the second, but it is visible.
This should be it. Let’s test this out.
Now when you login with correct credentials, you should be redirected to the /user-area
page which we now have.
You can see the name of the user after Hello text. And if you click “Logout” button you should be redirected to the Homepage.
And now if you try to manually go to the User Area page, you will be automatically redirected to the Login page.
And there you have it. In a few minutes we displayed our documents and built a simple authentication system.
Conclusion
Of course AppWrite offers much more functionality than what I showed in the last few minutes.
žWe haven’t even touched Cloud Functions, Storage and Webhooks. For that you will need to check out AppWrites documentation, which is always a nice thing to do.
But, as you could see AppWrites SDK is very simple and straight to the point, so implementing more complex functionality to your app or website should not be much of a challenge.