ブログを自作して公開しました

2020年12月1日

こんにちは、morikuniです。 ブログを自作してみたので、動作確認を含めてこのブログのアーキテクチャなどについて軽く紹介します。

大まかな構成

このブログは大まかに分けて、ReactのSPAを配信するWebサーバーと、記事を管理するGoのAPIサーバーの2つで構成されています。 基本的に、無料で運用できそうで管理が楽そうなプラットフォームに乗っかろうという思いで作ったため、ReactのSPA及び画像などのコンテンツはGitHub Pagesを使って配信しています。 GoのAPIサーバーについては、一回使ってみたかったという理由でCloud Runを採用しました。 同じように、一度使ってみたかったという理由で、ReactとGoの通信には、GraphQLを採用しています。 全体像はこんな感じです。

blog-architecture

使っている技術一覧

Frontend

  • TypeScript
  • React
  • Apollo Client
    • GraphQLのクライアント
  • styled-components
    • CSSをコード内に書いている
  • GraphQL Code Generator
    • GraphQLのクエリから型を生成する
  • GitHub Pages

フロントエンドの技術は正直よく分かっていませんが、GraphQLやりたい + CSSをコード内に書きたい + 型をやっていきたいという思いで選びました。

Backend

  • Go
    • GraphQLサーバー
    • Markdownで記事を書いているので、記事をパースするため
    • Markdownをバイナリに埋め込むため
  • Cloud Firestore
    • 記事の本文はMarkdownだけど、公開設定とかはFirestoreに入れてる
  • Cloud Build
    • DockerコンテナをbuildしてContainer Registryに置くために使ってる
  • Cloud Run

Goだと、GraphQLなら

gqlgen
というイメージを刷り込まれ済みなので
gqlgen
一択。 Markdown Parserはあんまりいいのがなさげだったので、一番有名そうな
blackfriday
を選択。 ファイルのバイナリ埋め込みは、Go 1.16のembedを待ちながら一旦
statik
でいいかなという気持ち。 GCP系は使ってみようというだけの選択となりました。

感想

正直普段GoのAPIしか書いていないので、フロントエンドの方は全てのことを調べながら書く必要があってなかなか大変でした。 いまだによく分かっていないことが多いけど、まあ動いているからOK!という気持ちでこのブログはリリースされました。

GraphQLも初めてちゃんとつかってみた訳ですが、感想としては「ブログ記事のような木構造のデータをGraphQLに載せるのは相性が悪いのでやめた方がいい」です。 GraphQLのクエリは、「このノード以下全部くれ」みたいな書き方ができないので、再帰構造になっているHTMLのリストなどを扱うのが面倒くさいことになります。 このブログでどうしたかというと、木構造を次の様にフラットな

Content
という型の配列に落とし込み、深度を表すための
level
というフィールドを持たせました。

1enum ContentType {
2    Header
3    Paragraph
4    CodeBlock
5    List
6    Quote
7}
8
9type Content {
10    type: ContentType!
11
12    texts: [Text!]!
13
14    # for Header, List
15    level: Int
16
17    # for CodeBlock
18    language: String
19}
20
21enum TextType {
22    Text
23    Code
24    Link
25    Image
26}
27
28type Text {
29    type: TextType!
30
31    text: String!
32
33    # for Link, Image
34    url: String
35}
36

スキーマには苦労したGraphQLですが、GraphQL Code Generatorもgqlgenも開発体験としてはかなりよかったので、GraphQLやっていき感は高まりました。

最後に、動作確認のために引用を使ってお別れです。

ここまで読んでいただき、ありがとうございました。