yikegaya’s blog

yikegayaのブログ

Vue +GoでPocketの記事にまとめてタグ付ができるサービスを作った

Pocketに記事をどんどん放り込んでいて整理できてない。。というモヤモヤがありPocketのAPIを使ってうまいこと整理できないかと考えてた。

https://ikeyu0806.hatenablog.com/entry/2021/05/09/113856

で、整理するならとりあえず記事にタグ付けできる機能があるんでそれを使うと良さそうなんだけど現状あんまり使えていない。

  • 公式のWebページからだと記事1つ1つ選択してタグ付しないといけないので面倒な気がする
  • 記事をクリップした時にタグ付けできるけどつける習慣がないので現状ほとんどついてない

なのでまとめてチェックボックスとかで選択してタグ付できる自分用Webサービスを作ってみたのでここまでの振り返りと感想を書いてみる。

画面こんな感じ

f:id:ikeyu0806720:20210528170348p:plain

ソースコード

github.com

使ってる技術

バックエンド: Go言語

選んだ理由

  • 仕事ではバックエンドはずっとRubyしか書いてないんでプライベートは静的型付け言語で書きたい。
  • 最近マイクロサービスの現場でよく使われてるんでその内触る機会があるかも
  • プライベートでちょっとしたもの作るのに良さそう
  • 構造体とか並行処理とかポインタとかスクリプト言語にはないいろいろな気づきが得られる。。気がする

フロントエンド: Vue

選んだ理由

  • 現状Reactとほぼ二択だけど仕事がReactなんで違う方触りたい

あとCSSフレームワークはなんとなくbuefyを使ってみた。

buefy.org

あと勉強のため以下の方針で作ってみる

  • 以前GoでHTTPサーバを作ったときはライブラリ使ったけど今回は標準ライブラリのみで書いてみる
  • Nuxtは使わずスクラッチでwebpackを書いてbundleする

開発環境

  • ホスト側での作業だとGOPATHの管理が面倒だったり将来的にサーバにあげようと思った時に楽なんでDocker上で作業した。
  • GoのサーバでWebpackでbundleしたjsを読み込んだHTMLをホストしてくれればいいしMySQLとかRedisみたいなストレージも今回は不要。なのでコンテナ一つで事足りるのでDocker Composeは使わない。
  • webpackはwatchコマンド付きでbundleしてbundle先のvolumeはDockerコンテナと共有する。これでいちいち再起動しなくても開発できる。

実装

やってることざっくり

クライアントのボタンを押すとバックエンドからPocketのAPIを叩いてリクエストークン取得→リクエストークン認証→アクセスキー取得→取得したアクセスキーを使って記事取得やタグ付をする。

よくあるWebのシステムで特に特殊なところはないかな。

面倒だったところ

Goでjsonを扱う場合、同じキー値とデータ型を持った構造体を定義してその構造体を基にjsonをパースしていくんだけどネストが深いとちょっと戸惑う

{
    "consumer_key": "コンシューマキー",
    "access_token": "アクセストークン",
    "actions": [
        {
            "action": "tags_add",
            "item_id": "528698205",
            "tags": [
                "プログラミング", "javascript"
            ]
        }
    ]
}

Goの構造体

type ModifyRequestParam struct {
    ConsumerKey string          `json:"consumer_key"`
    AccessToken string          `json:"access_token"`
    Actions     []*ModifyAction `json:"actions"`
}

type ModifyAction struct {
    Action string   `json:"action"`
    ItemID string   `json:"item_id"`
    Tags   []string `json:"tags"`
}

リクエス

# request_paramはVueからのリクエスト。Vueのフォームから入力したItemIDやTagが渡される。
modify_action := new(entity.ModifyAction)
modify_action.Action = "tags_add"
modify_action.ItemID = request_param.ItemIDs
modify_action.Tags = request_param.Tags

使ってみてどうなのか

  • タグ付は実際本家より楽にできるようになって快適になった気がする。
  • 記事一覧も本家だと画像付きで表示されて1画面で確認できる記事本数が少なかったり、クリックしたときに記事の元のリンクに飛んでくれず、Pocket内のサイトで文章が表示されるんで今回作ったサイトで見た方が快適な気がしている。

雑に作った割には結構使えるんじゃないかなこれ。 多分Pocket本家のサイトも有料プランがあるんで課金すれば便利に使えると思うんだけど無料枠だと流石に使いにくいところはあるので。

今後やりたいこと、課題

  • バックエンドの処理を並行処理にしていきたい
  • とりあえずローカルでしか動かない前提なのでアクセストークンの扱いはゆるい(有効期限なしでlocalStorageに入れてある)
  • いい感じに記事ソートしたいとかアーカイブもまとめてできるようにしたいとかUIもっといい感じに作れそう。。

とかやりたいこと諸々あるけど、とりあえずタグなしの記事にまとめてタグ付けして記事を整理しやすくなったので一旦当初の目的は果たせたかな。