「何を作りたいかが一番大事だよ?」。。。嫌というほどこの格言を聞いてうんざりしているそこのあなた!ほなまずブログ作りましょうや!
何を作りたいか聞かれても、すぐに思いつくぐらいならもうやってるねんと思いますよね。そんな方にはブログがおすすめです。理由は1.簡単に作れる、2.学びをアウトプットできる。この2点です。 そこで、このeBookではモダンな技術を使ってブログを作成する方法をご紹介します。今回は、人気プログラミング言語PythonのフレームワークであるDjangoを利用して作られたWebAPI作成用ライブラリの「Django REST Framework」と、JavaScriptライブラリのReactをベースに開発されたフロントエンドフレームワークの「Next.js」を利用してブログを作成します。また、フロントエンドのデザインには「MUI」を活用し、ブログ記事は「Markdown」形式で投稿できるようにします。
このブログを作成するにあたって、現在の私のPC環境を参考までに紹介します。互換性等は検証していないので、必要に応じてバージョンを変えてみてください。
今回のブログ開発の流れは大まかに以下の通りで紹介していきます。
なお、本ページでは「1. Django REST FrameworkとNext.jsの基礎知識とシステムの理解」についてご紹介します。
DjangoとはPythonをベースに作られたWebアプリケーション作成に使用されるフレームワークです。実際にこのブログ開発を始めてもらえば分かると思いますが、少ないコードで高品質のWebアプリケーションを作成できるため世界中で広く使われています。他のプログラミング言語でも同様のフレームワークはありますが以下がDjangoの特徴です。
blog_app/urls.py
という項目を見てもらえればイメージがつくと思います。blog_app/model.py
という項目を見てもらえればイメージがつくと思います。blog_app/admin.py
という項目を見てもらえればイメージがつくと思います。ここまでDjangoを褒めちぎりましたが、Djangoは実際のところ万能なのでしょうか?MTVの考え方に則っていることを特徴の一つとして挙げましたが、そのTemplate部分が強力かというと実はそうとも言い難いです。実際に完全にDjangoだけで作成された大規模なWebサイトはなかなか見つからないのではないでしょうか。それはあくまでベースとなっているPython自体がバックエンドのプログラミング言語ということもあると思います。ではどうすればDjangoのメリットも活かしつつモダンなWebサイトを作ることができるのでしょうか?それを実現するための鍵は、バックエンドとフロントエンドを分けてしまうことです、つまりバックエンドに特化したAPIサーバとしてDjangoを使用する(=DjangoをAPI化する)ことでよりパワフルに使いこなすことができます。前述の通りDjango REST Frameworkはサードパーティのライブラリですが、REST APIを利用する際に必要な機能に加え様々なプラグインも提供しています。通常のDjangoとプロジェクトの構成の面で比較すると、Djangoには「Form」や「Template」があるがDjango REST Frameworkにはなく、代わりに「Serializer」があるというのが大きな違いです。
ちなみに、「REST API(RESTful API / Representational State Transfer API)」とはWebAPIの一つで、Webアプリケーションで提供される全ての情報が一意なURLを有している形式のものです。クライアントがHTTPメソッド(GET, POST等)を用いてリクエストを送信するとJSONやXML形式でレスポンスが返されます。
下の図がDjango REST Frameworkのアーキテクチャになります。ファイル別にまとめようとするとゴチャっとなってしまうので単純化していますが、大体こんな感じで捉えておくと良いと思います。一部具体的なサービス名が書かれていますが今回はそれを利用するという意図で書いています。今回は「Webサーバー」とそこで動くプロジェクトの部分をNext.jsとVercelが担うという認識で大丈夫です。
HTTPメソッド別には下のような流れです。上図では便宜上、左右両矢印を使用していますが、GETorPOST、リクエストorレスポンスで使用しない部分もあるためめ、上図を参考にしつつ詳しくは以下のメソッドごとの説明をご確認ください。なお、「シリアライズ・デシリアライズ」の説明は【Part 2】で説明します。
project/urls.py
→app/urls.py
)の設定情報に基づき、適切なViewにルーティング→views.py
)がデータベースにアクセスしてクエリセット(オブジェクト)を取得→serializers.py
)してJSONに変換(※オブジェクトのままだとHTTPレスポンスが生成されないため。→project/urls.py
→app/urls.py
)の設定情報に基づき、適切なViewにルーティング→views.py
)内でリクエストデータをデシリアライズ(serializers.py
)してオブジェクトに変換(※オブジェクトのままだとデータベースが取り扱えないため)→serializers.py
)してJSONに変換(※オブジェクトのままだとHTTPレスポンスが生成されないため)→ReactがJavaScriptのライブラリであることについては触れましたが、Next.jsの前提となっているので一旦ここで整理しておきましょう。ここではReactの特徴を4つのポイントで簡単にまとめました。
宣言的UI
コンポーネント指向
状態管理
仮想DOM
他にもReactの特徴は色々とありますが、上で挙げた4点が有機的に絡み合うことでReactの基礎が成り立っています。
Next.jsは冒頭の説明通り、Reactベースの人気のあるWebアプリケーションフレームワークです。ReactベースなのでNext.jsのコードを実際に見てみるとReactでよく使われるモジュールや書き方もたくさん見つかるとは思いますが、ここではNext.jsの特徴的な機能を3点まとめてみました。
手法 | SSG | SSR | ISR | CSR |
---|---|---|---|---|
正式名称 | Static Site Generation | Server-Side Rendering | Incremental Static Regeneration | Client-Side Rendering |
概要 | ビルド時にAPIからデータを取得してHTMLのページを生成(「プリレンダリング」)。クライアントからのリクエストに対してはこのHTMLが返される。 | リクエスト毎にサーバー側にHTTPリクエストしページをレンダリング、クライアント側で描画。 | 事前にページを生成して配信しつつ、アクセスに応じてページを部分的に再生成して新しいページを配信する。 | ビルド時にレンダリングせず空のファイル(HTML, CSS, JS)を取得。その後ブラウザで初期レンダリング後に非同期で差分を埋める形でデータを取得し表示する。 |
メリット | リクエストごとにHTMLを生成せず、事前にビルドされたHTMLを再利用する形となるため、SSRよりも高速で表示可能。 | 初回読み込み時にはクライアントからAPIを叩かないので早く表示される。リアルタイム更新に向く。 | 生成ページのキャッシュが任意のタイミングでできるため表示が速く一定時間毎に更新可能。 | リアルタイムでデータ更新が可能で、ページ遷移が早い。ユーザー体験が良い。SSG・SSR・ISRと同時に利用可能。 |
デメリット | データ更新の度に再ビルドが必要なためリアルタイム更新と相性が悪い。 | リクエストが多く発生する場合サーバCPUへの負荷が大きい。 | Vercel+Next.jsでしか利用できない。古くなったページがキャッシュで返される可能性がある。 | 初回表示に時間がかかる。SEOに向かない。OGP表示ができない。 |
利用する関数 | getStaticProps | getServerSideProps | getStaticProps | useSWR等 |
データ取得タイミング | ビルド時 | ユーザーリクエスト時 | ビルド時 | ユーザーのリクエスト時 |
利用用途 | HP | SNS・動画投稿サービス | ニュースサイト・ブログ | ダッシュボード |
ファイルベースルーティング
react-router-dom
というライブラリを使用しますが、Next.jsでは/pages
ディレクトリ以下にファイルを作成すると、そのファイル名がそのままURLとなります。例えば/pages/about.js
ファイルを作成すると、aboutがそのままURLとなるイメージです。他にも/pages
ディレクトリ直下のindex.js
ファイルにページを構成する記述をするとそれがそのままトップページとなり、/pages
ディレクトリの下にサブディレクトリを作成すると、index.js
ファイルがそのままディレクトリ名のURLとなります。/pages
ディレクトリ下のサブディレクトリ内で作成する1つのファイル(/pages/sub/[slug].js
や/pages/sub/[id].js
)を複数のURLに紐付ける手法です。これにより、1つだけファイルを作成すれば同じ形式を持つデータを当てはめるだけで大量のページを作成できるため、効率よく統一感のあるページを作成します。ブログ作成等に利用されます。ファストリフレッシュ
今回のブログ作成にはMUI(旧Material-UI)を使用しています。MUIとはReact用のコンポーネントライブラリでGoogleが提唱する「Material Design」というデザイン体系のガイドラインをベースに作られています。MUIを使うことで以下のようなメリットがあります。
最後にMarkdownについての紹介です。こちらはプログラミング言語等とは違い、誰でも簡単にウェブ上で文章を書けるようにテキストをHTMLに変換することができるようにした記法を指します。詳しくはMarkdownの書き方とPros & Consの記事でまとめていますので、気になる方はこちらを参考にしてみてください。
今回はローカルでのブログ完成をゴールにしているので分かりづらいですが、デプロイ時には「Web3層アーキテクチャ」への準拠することを前提にブログを作成しています。Web3層アーキテクチャとは、プレゼンテーション層、アプリケーション層、データ層の3層構造に分割したWebアプリケーションのアーキテクチャです。
レイヤー | サーバ | 詳細 | ツール |
---|---|---|---|
プレゼンテーション層 | Webサーバ | Webブラウザ等を通してクライアントとやり取りをし、静的データを取り扱ってUIを構成する。 | Apache, Nginx |
アプリケーション層 | アプリケーションサーバ | Webサーバからのリクエストを受け、バックエンドのプログラミング言語による処理を実施する。 | uWSGI, gunicorn |
データ層 | DBサーバ | Webサイトの構築に必要なデータの保存・抽出を担当する。 | RDBMS (PostgreSQL, MySQL), NoSQL (Redis) |
今回のブログ作成には含んでいませんが、DRFについては最終的には「Heroku」へのデプロイ、Next.jsについては「Vercel」へのデプロイを想定してそれぞれプロジェクトを作成しています。Django REST Frameworkのアーキテクチャのセクション内の画像ではアプリケーションサーバーが「Django REST Framework」の外側にありますが、実際にHerokuにデプロイする際には「gunicorn」を設定するため、デプロイ後はHerokuのDynoというコンテナ内にアプリケーションサーバーとしてのgunicornとDjango REST Frameworkプロジェクトが設置される建て付けとなります。またデータベースとしてのPostgreSQLについても、デプロイ後は厳密には「Heroku Postgres」となります。
【Part 1】 では今回のブログ作成に使うライブラリ・フレームワーク・ツールについて紹介しました。【Part 2】と【Part 3】ではそれぞれDRFプロジェクトとNext.jsプロジェクトの開発に入っていきます。