Have you heard about Envirotechnical? Let's fight climate change one byte at a time :) Learn More →

logo
Published on

The Scrooge's path to Github API for data storage

Authors
Table of Contents

The why

Imagine being that one person who really doesn't want to spend a single penny on a service that might make your life easier.

You know the solution to the problem right? There's actually 2.

  1. Code your own solution
  2. Find an alternative solution free of charge that's gonna take effort to build

I'm a Pareto afecionado, you know, the 20/80 rule kind of person.

 

Github meets Developers meets Scrooge

Now, let us be serious for a moment (Aha! Gotcha!) and pretend we don't know what we are looking for.

I needed a way to store hashed/salted subscribers' emails without spending a dime and without putting my credit card out in the wild.

At first I thought:

 

Try Azure Functions without credit card

But the authorization layer hit me with a blockade when I told them that I'd rather use a prepaid card for this kind of situations. Apparently Revolut's not good enough, but that's not on me, I love their services! I was about to e-mail my good friend Bill when a wonderful idea took advantage of the timing.

The idea was simple, maybe beautiful, too simple. I had to let it slide.

I thought again. I should use my own VPS, but I didn't want to install packages and whatnot. I figured I could give a try to Netlify Functions, but that didn't fancy me either.

How would you have your Vercel hosted NextJS application POST freely to some kind of data storage?

Github hosted solution

The how

That was it. The simple and beautiful idea paved the way to greatness!

A simple concept.

  1. Read Github's RESTful API
  2. Pick a fetch, any fetch
  3. Hate yourself for not exec('curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/{resource}')
  4. Generate a secret token and use it like process.env.SECRET_TOKEN
  5. Remember to NEVER EFFIN DEPLOY YOUR SECRET TOKENS TO THE INTERNET
  6. Drink a cup of coffee, or tea
  7. Bask in the glory of Github Issues RESTful endpoints

Now that you have pretty much everything you need, just read the code:

export default async (req, res) => {
    const SECRET_TOKEN = process.env.SECRET_TOKEN // Vercel environment variable or .env configuration
    const user = 'yourusername'
    const repo = 'yourrepository'
    const data = {
        'amount_of_wows': 9001,
    }

    let issue = {
        "title": "A title for your issue", // this field is required
        "body": `A body for your issue that can contain ${JSON.stringify(data)}`, // this is necessary for our intent
    }

    fetch(`https://api.github.com/repos/${user}/${repo}/issues`, {
            method: 'post',
            body:    JSON.stringify(issue),
            headers: {'Content-Type': 'application/json', 'Authorization': `token ${SECRET_TOKEN}`}
        })
        .then(res => res.json())
        .then(json => {
            console.log(`Issue created`)
            return res.status(200).json({ issue: issue })
        });
}

As you might have noticed, I'm using NextJS api routing so I'm nesting the logic for my call directly in the filesystem. One very important thing that you should do is adding a security layer to this endpoint.

import { getSession } from "next-auth/react"

export default async (req, res) => {
  const session = await getSession({ req })
  if (session) {
    // Signed in
    // Previous codeblock...
  } else {
    // Not Signed in
    res.status(401)
  }
}

You should always protect your routes when in doubt.

So, now that we have the code at our disposal, we can call our endpoint to engage in the creation of a new Github Issue. And you know what that sounds like?

Key, Value pair storage for free.

Github Issues RESTful API tutorial

The goodies

Always remember that Github Issues might be visible to anyone if your repository is set to public. If that is the case you might want to avoid storing sensitive data.

The goodbye

I hope you found this article useful and to your liking and if you have any requests, drop a message on one of my social media accounts or open an issue/start a discussion on github, on this repository!