- Published on
Go Keep - Clone of Google Keep
- Authors
- Name
- Srinjoy Santra
- @s_srinjoy
Go Keep
I was going through John Crickett's Coding Challenges and Build Your Own Google Keep caught my eye. I thought why not build a clone's of Google's product with a language designed by their own developers.
the killer functionality of Google Keep [is] being a simple to use distributed note taking tool with a mobile and web UI.
I decided to build the backend service in Go and left out the frontend (for some future date?).
API Design
The entire design hinges on Creation, Read, Updation and Deletion (CRUD) of a Note (reource entity).
For authentication, there are four more endpoints for login, callback, logout, and fetch user details.
The new release of net/http
has eliminiated the use of any router and URL matcher and I have stuck to using the standard library.
Authentication
Without authentication basically anyone can read your notes. We need to introduce session management that link authentication and authorization (access control).
HTTP is a stateless protocol, where each request and response pair is independent of other web interactions. The session ID or token adds authentication credentials to the user HTTP traffic and the appropriate access controls enforced by the web application.
I could have rolled out my own implementation of authentication. One good library for it is Goth. I thought of exploring a pre-built identity solution like KeyCloak, Firebase etc. I chose Auth0.
Auth0 documentation recommends the use of gin sessions. I wanted to write my own session management code. To draw inspiration, I adopted code from Acebond/session. It is a fast-in-memory backend session storage middleware. I spent significant time here; going through documentation and coming up with a working solution.
Cookies store the login information on the client's device which is validated at backend by the session middleware.
Database design
I usually use MariaDB (MySQL) at work, so to shake things up I tried out Postgres.
create table customer
(
id uuid not null
constraint user_pkey
primary key,
name varchar not null
constraint customer_pk
unique
);
create table note
(
id uuid not null
primary key,
title text not null,
content text not null,
updated_at timestamp default CURRENT_TIMESTAMP not null,
"userId" uuid not null
);
The uuid generation is handled at the server. I preferred using uuidv7 because it makes time based queries more efficient and intuitive.