title: [Learning Notes][Golang] Using Github Issues as a Database
published: false
date: 2023-02-15 00:00:00 UTC
tags:
canonical_url: http://www.evanlin.com/go-github-issue/
Preface
I've mentioned before that many databases have started charging fees, so it's actually quite troublesome to find a free database to use. Whether using Heroku or Render databases, it's a significant expense. Therefore, I often come up with strange ideas to use some unusual storage methods as databases. Today's article will use the Github Golang API to use your personal (Private Repository) issues as a database.
Open Source Package https://github.com/google/go-github
How to Obtain a Github Token
First, to use the Github API, you need to obtain a Github Token. Here's the process:
Open Settings
Select Developer settings
Here, select Personal Access Token, and remember to choose Tokens (Classic)
This allows you to obtain a developer Access Token. Remember not to lose it (or don't store it on github).
Prerequisites and Methods for Using Github Issues as a Database
API Rate Limit
If you want to use this method as a database, you must first ensure that your data format is quite simple. Or, your data access has relatively low traffic. Because the Github API has Rate Limit information, which may be as follows:
- Core:
- Limit: 5000 (60mins)
- Search:
- Limit: 30 (60mins)
- GraphQL:
- Limit: 5000 (60mins)
Data Placement Suggestions
- Title: Database Name
- Each comment can be considered a record
- Each Comment can be separated by csv (comma-separated), or by other methods.
- Tags can help you quickly find similar Titles
These are just some suggestions; the following code example is simpler. It's just a Key -> Value method of storage. The Key is placed in the Title, and the Value is placed directly in the first Comment.
Related Code:
Basic Structure
type GithubDB struct {
Name string // github owner name
Repo string // repo name (can be private)
Token string // the Access Token just obtained
Client *github.Client
}
Initialize Github Client
func createGithubClient(token string) *github.Client {
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
tc := oauth2.NewClient(ctx, ts)
return github.NewClient(tc)
}
Save Github Issue (Create)
At this time, you need to provide the username Name and Repo name.
func (u *GithubDB) saveIssue(title, body string) error {
input := &github.IssueRequest{
Title: String(title),
Body: String(body),
Assignee: String(""),
}
_, _, err := u.Client.Issues.Create(context.Background(), u.Name, u.Repo, input)
if err != nil {
fmt.Printf("Issues.Create returned error: %v", err)
return err
}
return nil
}
Find Title (key) Get by Title
func (u *GithubDB) getIssue(title string) (string, int, error) {
ret, _, err := u.Client.Search.Issues(context.Background(), title, nil)
if err != nil {
fmt.Printf("Issues.search returned error: %v", err)
return "", 0, err
}
log.Println("issue ret:", ret)
for _, v := range ret.Issues {
log.Println("return issue:", v)
log.Println("Issue Num:", v.Number)
log.Println("Body:", v.Body)
log.Println("Comments:", v.Comments)
}
return *ret.Issues[0].Body, *ret.Issues[0].Number, nil
}
Update the data inside (Update)
func (u *GithubDB) updateIssue(number int, title string, updatedCnt string) error {
updateIssue := &github.IssueRequest{
Title: String(title),
Body: String(updatedCnt),
Assignee: String(""),
}
ret, _, err := u.Client.Issues.Edit(context.Background(), u.Name, u.Repo, number, updateIssue)
if err != nil {
fmt.Printf("Issues.edit returned error: %v", err)
return err
}
log.Println("Issue updated:", ret)
return nil
}
Future Development
In fact, when doing some simple example programs, if your database itself doesn't have too many field requirements, and the amount of access itself isn't very large, you might consider storing your data through Github Issues. Firstly, your database is "visualized," and you can also save some unnecessary extra costs.




Top comments (0)