Disclaimer
Note: As the tutorial I used showed some bad procedures, I will of course not link it here.
Where we are
To have a basis for this article, let's first have a look at my EtB item recovery project. Currently, it is a Discord bot that helps players who are playing on my Minecraft server and have died due to a bug to get their items back. The system is written in Python and works with MongoDB, a document-based database. I have written more information in the Github repo.
Why I need an API
A friend of mine wants to create a website for a subsequent season. He would like to create a web interface in this website, with the help of which it will be even easier to submit applications and edit them as a team member. In order to separate the systems from each other for security reasons and because I want to give him absolute freedom over his work, I wanted to create a separate API to interact with the database.
Choosing a programming language and framework
I think everyone knows what programming language I'm going to use: NodeJS. Precisely because this programming language is so often recommended, I will use it. I already have a little experience with ExpressJS from other projects and for this reason I will use it (for the time being) to handle the annotations.
Geting started
Get user data
This part was quite simple. I take the Discord userid from the url, search for it in the database (not mongoose, by the way, but the first-party driver) and return the result. For simplicity, I will not show the functions here.
If you have looked at this code, you will probably have seen how the authorisation is done incorrectly. In my defence: This is exactly how it was done in the YouTube tutorial I followed. And now, frankly, I'm too lazy to correct it.
Put user data
This part was then a bit more complicated, but the MongoDB driver took care of a lot for me and since I know that only one person will be using this API and that they can get back to me quickly in case of queries, I did without a strong validation of the sent data. If it bothers anyone, they should please start a pull request as soon as the project is made open source. The "difficult" part is done in the function I use, otherwise the code is quite similar.
Delete user data
The code here is somewhat similar to the GET request because of the simplification. Same game, the magic happens in the omitted functions, but you've probably seen them a thousand times in your life and can imagine what's going on in the background.
A new task: Discord-OAuth
After some consideration, we chose the Discord login as the authentication method for the members-only area. We only check if the user is on our Discord server, which he only is if he also participates in the project.
The actual handling of the requests was quite simple according to my experiences from the previous functions. The problem was that all the npm modules I selected wouldn't work. After I had to discard discord-auth, discord-oauth, discord-oauth2 and finally also the actually quite promising project disco-oauth due to some bugs, I finally implemented the methods myself, but with some inspiration from disco-oauth. It's a great project and I assume that the bug that caused me to not be able to use it is my fault.
Documentation
...I really didn't have to create it at all. Inspired by the Hypixel API, however, I felt like exploring this topic area using my practical example. I ended up using ReDoc and OpenAPI and in the end the documentation looks quite solid, even if I had some problems with the OpenAPI syntax mainly due to my strange authentication. If anyone ever plans to host this documentation on Github pages, they should probably use this command:
npm run build && redoc-cli bundle ./dist/openapi.yaml --output ./dist/index.html
Together with Github Actions it might look like this.
In the end, I'm very happy with the hosting by Github Pages, but I'm planning another post on that.
By the way, my final product is publicly available for everyone: https://explorethebuild.github.io/etb-item-recovery-api/
Hosting
Vercel serverless functions
When I thought of free web hosting, Vercel immediately came to mind. They are actually there to host static sites, but they also have a product called "Serverless functions". That's exactly the right thing for me. But implementing my API was difficult - again because of my authentication via the request body. So I stopped my attempts with Vercel and started looking for other possibilities.
Firebase functions
Another product that offers great, free products is Firebase from Google. But the journey was quickly over after some browser problems, as the functions are not included in the Spark plan (the free one).
Supabase
Supabase, a supposed alternative to Firebase, already made me turn back at the start page. Their Serverless Functions are still under development and will only be released in the near future.
...and again: Vercel serverless functions
In the end, I tried Vercel one last time. Because of the same syntax, I quickly transferred my project to the NextJS programming language. Now everything went without further problems and I host my API with Vercel without any costs.
Conclusion
This journey has shown me a lot and I think I now know how to create a proper API. My friend will be able to work with this API and that was always my goal in the end. Maybe I'll use GraphQL next time. We will see.