Open21

SNSサービスを作ってみる

takecchitakecchi

概要

  • Xからの移住先を探し中
  • 廃人って程ではないので、ちょうどいいサービスが欲しい
  • 今触れたい技術に触りたい

→ SNSを作ってみよう。

ということで環境構築や実装時の悩み、考えのアウトプットをする。

takecchitakecchi

なぜ移住できない

Xのいいところ

  • 一つのサービス(X)で完結しており、呟かれる情報が多い
  • なんだかんだ人が多い
  • 全文検索ができる
  • コミュニケーション以外のことで重宝してるかも
  • レスポンス速度が速い(安定したサービス)
  • おすすめポストが意外と刺さる

Xの嫌なところ

  • デフォルトカラムがおすすめ
  • シャドーBAN
  • 実質的なサードパーティサービスの廃止
  • インプレッション目当ての中身のないポスト
  • TweetDeckの廃止

X以外の選択肢

  • 非営利は今後が不安、推進力やメンテナンス、運営コスト。
  • Xとは少し違った特色がある(そこは求めてない)
  • サービスが不安定
  • 全文検索ができない(主に分散型)
  • すでに形成されたコミュニティ(主に分散型のLTLと言われるもの)
  • インタンスに迷う(主に分散型)

総評

結局求めていたのは脱"中央集権型"を掲げた"連合型分散型"や"リレー型分散型"のSNSではなく、昔のTwitterだったのでは?

(発言したことに対する責任は伴うのは当然として)勝手にシャドーBANされたり、サードパーティがいきなり締め出されたり、利用者を無視した改悪を繰り返す"中央集権型"が好まれないだけで、"中央集権型"という仕組み自体は悪いとは思わない。

takecchitakecchi

検索周りで問題を抱えていたり、クローズドなコミュニティの形成が為されている分散型自体があまり自分に刺さらないのかも。

実は目新しい機能要らなくて、求めていたのは2015年頃のツイッターなのでは

takecchitakecchi

技術選定

  • TypeScript
  • Next.js ... AppRouter色々言われがちだけどやっぱり触ってみたい
  • PostgreSQL
  • NestJS
  • GraphQL ... SNSには不向きかも?でも触ってみたい
  • sqldef ... 良いという話を聞いた
  • Prisma ... ぶっちゃけ生SQLでいいけど、実際に触って評価したい
  • AWS ... スケーラブルな構成に出来る。いざという時はマシンパワーで解決できる為
  • AWS CloudFront ... Vercel以外にNext.jsを載せてみたい。爆速と聞いたから試す
  • Elasticsearch ... 全文検索用。
takecchitakecchi

サーバーサイドキャッシュはredis?

redisに載せて配信と登録を同時にやるみたいな構成にしてもいいけど、
後で拡張できるので困ったらその時に検討

takecchitakecchi

原則

  • スケールアウトができること
  • 将来的に負荷がかかっても耐えられるような設計
takecchitakecchi

インフラ構成 (AWS)

  • バックエンド ... [ALB] -> [ECS Fargate] -> [RDS]
  • フロントエンド ... [CloudFront] -> [S3] or [lambda]
takecchitakecchi

@svgr/webpack + Storybook周りでハマったことメモしておけばよかったな

takecchitakecchi

ドキュメント拡充のためにConfluenceを使用
ConfluenceとかGithubとか月額賄えるようにはなりたい...

takecchitakecchi

認証の話

バックエンドはNestJSで開発しているので、公式ドキュメントを眺めてみる。
https://docs.nestjs.com/security/authentication
https://docs.nestjs.com/recipes/passport

passportを使用した方法も紹介されてるけど別にどっちでもいい。
JWTであればセッションと違ってスケールアウトした時にredisとか噛ませなくて良いのがいいなくらい

takecchitakecchi

将来的に鍵アカウントが実装されると権限がなくても見えるものと、見れないものが混在することになると思われるので、認証が任意のエンドポイントが生まれることになる。

認証が任意なGuardを作成する。

takecchitakecchi

バックエンドの話

ECSコンテナで複数台立ち上げてスケールアウトできるような構成にする。

takecchitakecchi

AWSの話

いざガッツリ触ってみると意外とわからないことが多い。

takecchitakecchi

ざっくりと以下のことをやった

VPC

  • InternetGatewayを作成 ... 外部公開用
  • PublicSubnet ... ALBとか置くところ
  • PrivateSubnet ... ECSとRDSとか置くところ
  • NatGateway ... DockerコンテナをECRから落とすのに必要だった

RDS

  • PrivateSubnetに配置
  • securitygroupの作成 ... rds接続用

Bastion(jump)サーバの作成

RDSに接続するための踏み台サーバ

ECSClusterの定義

takecchitakecchi

Next.js ハマりポイント(?)

useRouternext/navigationのものを使いStorybookでappDirectoryをtrueにする。

  • app routerを使用する場合はuseRouternext/navigationのものを使う
  • Storybookでエラーが出るため、以下のように指定
export const Default: Story = {
  parameters:{
    nextjs:{
      appDirectory: true
    }
  },
};
takecchitakecchi

NestJSでbigintを使用するエラーになる

標準のJSONパーサーがbigintに対応していないため。
Swaggerはint64として吐き出してくれるようなので、NestJSのデフォルトのパーサーを変更すれば良い?

takecchitakecchi

swaggerがint64で出してくれてもswagger-codegen(typescript)でクライアントを生成するとnumberになってしまった。
なので諦めて、リクエスト/レスポンスとして使うオブジェクトではbigintは使わずstringとすることにしました。
OASはちゃんと出てるだけに残念。クライアントを自前で作るのも手間なのでできれば自動にしたいという事もあり断念