Myreads, a digital bookshelf using Golang, React with Typescript, HarperDB, JWT based auth, and Docker

Myreads, a digital bookshelf using Golang, React with Typescript, HarperDB, JWT based auth, and Docker

A complete web-based application using the RESTful API architecture consisting of frontend, backend, and database.

ยท

6 min read

Hello everyone, to participate in HarperDB+Hashnode Hackathon I'm submitting this complete web-based application called Myreads which lets us maintain our offline bookshelf digitally. This is a full-stack application having backend, frontend, database service deployed using docker-compose.

Little bit about me

My name is Pratik. I'm a system-level software developer and tester who works mainly with Linux and containers. I'm a Linux enthusiast and love open-source technologies. I don't have any professional experience in developing web-based applications. This project can be considered my first web-based project.

Inspiration behind this project

For a long time, I was thinking to get started in the web development field as I already work on system-level programming with containers, adding web development to my portfolio could make it a full-stack developer. I also like to read books. Everyone who loves reading books keeps count of their books or maintains the status of books present on their shelf. So I thought why not build something in this area and I built the Myreads. Inspired from Goodreads

What is Myreads

Myreads is a simple but utilitarian web-based application that helps you to maintain your book status in three categories:

1. Wish List: Books which you want to read.
2. Reading List: Books you're currently reading.
3. Finished List: Books you finished reading.

How I build it?

Tech stack

Main tech stack:

  1. HarperDB as database service
  2. Golang for backend server
  3. React with Typescript for UI
  4. Docker compose to deploy the application

Underlined tech stack:

  1. git, git-submodules
  2. go-fiber
  3. harperdb-sdk-go
  4. containers
  5. react-bootstrap, react-query, etc...
  6. HarperDB docker instance

Challenges

As I'm new neophyte in web development, I faced lots of challenges.

  • Learning frontend technologies

I come from more of a back-end technology background, so learning front-end and creating a project using it in a small period of time was a bit challenging. But after many sleepless nights and countless hours of going through tutorials, I got hang of it.

  • HarperDB's support for Golang

When I started researching HarperDB, I found almost no tutorial about Golang+HarperDB. This was one of my motivations to write backend using Golang so I could create some content of Golag+HarperDB. I found one small library harperdb-sdk-go, which supported the basic CRUD functionality but does not provide all the functionalities needed to write the webserver which deals with the database. But I still managed somehow and wrote my own wrapper whenever it was needed.

  • Model migration

Almost all the MVC based library supports the migrating model to the database table which was not yet supported by the harperdb-sdk-go. So I had to find another way to initialize the database using curl commands in a shell script.

Myreads System Design

System design is simple and elegant.

We've three services running: frontend, backend, and database. Frontend makes the API call to the backend then backend verifies the authenticity of the API call and takes the required action accordingly.

Myreads backend service

Myreads backend is written in Golang using Fiber and harperdb-sdk-go. Backend exposes a list of API which are then consumed by the frontend.

1. /api/register: For user registration.
2. /api/login: For use login.
3. /api/user: To fetch the logged-in user information.
4. /api/logout: To log out the user.
5. /api/books/add: To add book the database.
6. /api/books/all: To fetch all the books.
7. /api/books/reading: To fetch books from the reading list.
8. /api/books/wishlist: To fetch books from wishlist.
9. /api/books/finished: To fetch books from the finished list.
10. /api/books/deletebook: To delete book
11. /api/books/updatestatus: To update the status of the books such as reading->finished.
12. /api/static: To fetch the static content such as the image.

This is a standalone service so it can be spun up using docker and could be tested using POSTMAN or CURL.

Myreads frontend service

Myreads frontend is written using React with Typescript. It consumes the APIs exposed by the backend.

This service is also standalone it can be used with any other backend service which will expose the same set of APIs as the Myreads backend service.

Myreads database service

Myreads backend service is hardcoded to use the HarperDB. The schema has two tables users and books. Users table is to store the user-related information such as name, email, and password. Books table is to store books related data such as name, author, description, imageLoc, userid of the book's owner.

Application walkthrough

  • Every new user will have to register themself at the registration page.

Screenshot from 2021-06-26 02-52-37.png

  • After successful registration user will be redirected to the login page.

Screenshot from 2021-06-26 02-52-34.png

  • After login, the user will be redirected to the home page where he can see all the books from his bookshelf. Screenshot from 2021-06-30 02-03-16.png

The new user will see the warning in the Red saying empty bookshelf. Screenshot from 2021-06-30 02-04-40.png

  • User will need to fill a form to add books to the bookshelf.

Screenshot from 2021-06-26 02-52-30.png

  • Then a user can visit the home page or the category page to see their book. Below is a screenshot of the reading category of the book.

Screenshot from 2021-06-30 01-43-17.png

  • Each book on the bookshelf has a green colored more button. On clicking it will prompt with the book description and two operation choices to perform on the book.

    1. Update the status of the book(wishlist, reading, finished)

    2. Remove the book from the bookshelf.

Screenshot from 2021-06-30 01-58-33.png

Deploying the Myreads

This is a multiple service-based application so it makes sense to use containerization to deploy it.

I've containerized frontend and backend services whereas the database service is handle by the HarperDB cloud instance.

Follow the following steps to deploy the application.

  1. Get the powerful free HarperDB instance by visiting this link

  2. Create New HarperDB Cloud Instance (one instance is free) and remember the username and password of the instance.

  3. Once the instance is up and running click on the instance card and go to the config section.

    • In the config section, you'll see the Instance URL and Instance API Auth Header (this user) copy them. They're needed to interact with DB.
  4. Make sure you've docker and docker-compose installed and running successfully.

  5. Clone the project repository from Github. This repo contains sub-modules of frontend and backend services so we'll need to clone it with --recurse-submodules flag. Project source code: https://github.com/pratikjagrut/myreads-harperdb

    git clone --recurse-submodules https://github.com/pratikjagrut/myreads-harperdb.git
    cd myreads-harperdb
    
  6. Update the .env file with your harperDB database credentials. In the root of the myreads-harperdb directory, it has a .env file that contains the database and API connection-related environment variables.

    DB_HOST=
    BASIC_AUTH_TOKEN=
    HDB_ADMIN=
    PASSWORD=
    PORT=8000
    API_URL=http://localhost:8000
    

    DB_HOST, BASIC_AUTH_TOKEN, HDB_ADMIN and PASSWORD we've already obtained this information in the 2nd and 3rd steps.

    DB_HOST=Instance URL from 3rd step
    BASIC_AUTH_TOKEN=Instance API Auth Header (this user) from 3rd step
    HDB_ADMIN=username from 2nd step
    PASSWORD=password from 2nd step
    
  7. If all the above steps were successfully followed then hit the docker-compose

    docker-compose up
    
  8. Once all the services are running perfectly fine you can visit the http://locahost:3000/ and see the application is up and running.

Screenshot from 2021-06-26 02-52-34.png

NOTE: If something goes wrong and you wish to check the logs of individual services run the following command.

docker-compose logs server # To check the backed service logs
docker-compose logs web-ui # To check the frontend service logs

Did you find this article valuable?

Support Pratik Jagrut by becoming a sponsor. Any amount is appreciated!

ย