エミ眠太の自由帳
 エミ眠太の自由帳
    
 
 eBook      2023-08-12      

Django REST Framework + Next.js (MUI) + Markdownでブログを作る【Part 1】

Language:
 Markdown Python Node.js JavaScript
Framework/Library:
 Django Django REST Framework React Next.js MUI(Material-UI)
Technology:
 環境構築 REST API Web API MVC 状態管理 仮想DOM Material Design Web3層アーキテクチャ
Platform/Tool:
 Heroku Vercel PostgreSQL Heroku Postgres gunicorn

記事一覧へ

目次


はじめに

「何を作りたいかが一番大事だよ?」。。。嫌というほどこの格言を聞いてうんざりしているそこのあなた!ほなまずブログ作りましょうや!

何を作りたいか聞かれても、すぐに思いつくぐらいならもうやってるねんと思いますよね。そんな方にはブログがおすすめです。理由は1.簡単に作れる、2.学びをアウトプットできる。この2点です。 そこで、このeBookではモダンな技術を使ってブログを作成する方法をご紹介します。今回は、人気プログラミング言語PythonのフレームワークであるDjangoを利用して作られたWebAPI作成用ライブラリの「Django REST Framework」と、JavaScriptライブラリのReactをベースに開発されたフロントエンドフレームワークの「Next.js」を利用してブログを作成します。また、フロントエンドのデザインには「MUI」を活用し、ブログ記事は「Markdown」形式で投稿できるようにします。

開発環境

このブログを作成するにあたって、現在の私のPC環境を参考までに紹介します。互換性等は検証していないので、必要に応じてバージョンを変えてみてください。

  • PC・・・MacBook Pro (13-inch, M1, 2020)
  • OS・・・macOS Monterey (12.2.1)
  • Python・・・3.10.8
  • Node・・・18.7.0

開発の流れ

今回のブログ開発の流れは大まかに以下の通りで紹介していきます。

  1. Django REST FrameworkとNext.jsの基礎知識とシステムの理解
  2. Django REST FrameworkでWebAPI作成
    1. 環境構築
    2. Project設定
    3. App設定
  3. Next.jsでUI作成
    1. 環境構築
    2. コンポーネント設定
    3. ページ設定

なお、本ページでは「1. Django REST FrameworkとNext.jsの基礎知識とシステムの理解」についてご紹介します。

1. Django REST FrameworkとNext.jsの基礎知識とシステムの理解(+その他基礎知識)

Django REST Frameworkの基礎知識とシステムの理解

Djangoの基礎知識

DjangoとはPythonをベースに作られたWebアプリケーション作成に使用されるフレームワークです。実際にこのブログ開発を始めてもらえば分かると思いますが、少ないコードで高品質のWebアプリケーションを作成できるため世界中で広く使われています。他のプログラミング言語でも同様のフレームワークはありますが以下がDjangoの特徴です。

  1. MTV(Model-Template-View)フレームワーク
    • 他のWebアプリケーション開発用のフレームワークでは「MVC(Model-View-Controller)」という概念のもと成り立っていることが多いですが、Djangoは「MTV」という概念のもと作られています。この2つは何が違うのでしょうか?Model(M)の部分については両者同じようなものと捉えても問題ありませんが、View(V)については考え方が違います。MVCにおけるView(V)はどんな(What)データをどのように(How)見せるか定めていますが、MTVにおけるView(V)は見せるデータ(M)のみを定めており、見せ方(How)についてはTemplate(T)に一任しています。つまりDjangoではMVCにおけるView(V)がView(V)とTemplate(T)に分割されているんですね。ちなみにMVCにおけるController(C)の部分についてはリクエストに応じて「URLディスパッチャ」がViewと紐付いたURLに振り分けをしています。
    • URLディスパッチャについては、2. Django REST FrameworkでWebAPI作成のページにてblog_app/urls.pyという項目を見てもらえればイメージがつくと思います。
  2. ORM
    • Djangoにおいては、SQLクエリを使用せずにPythonコードを使用してデータベースが操作可能です。これによりCRUDの簡素化が期待できます。
    • 詳しくは2. Django REST FrameworkでWebAPI作成のページにてblog_app/model.pyという項目を見てもらえればイメージがつくと思います。
  3. 高セキュリティ性能
    • Djangoはセキュリティ対策には特に力を入れているフレームワークだと言われており、クロスサイトスクリプティング(XSS)対策、クロスサイトリクエストフォージェリ(CSRF)対策、SQLインジェクション対策等のための機能が備わっています。ただし、Djangoが推奨する書き方・作り方を遵守していることが前提です。
  4. 管理サイトの自動生成
    • 管理サイトが予め備わっている点については筆者も大変気に入っています。いかほど楽に利用できるかについては、2. Django REST FrameworkでWebAPI作成のページにてblog_app/admin.pyという項目を見てもらえればイメージがつくと思います。
  5. 拡張性
    • Python自体においても言えることですが、サードパーティライブラリをサポートするDjangoは拡張性の高さも売りです。今回利用するDjango REST Frameworkもサードパーティのライブラリです。

Django REST Frameworkの基礎知識

ここまで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のアーキテクチャ

下の図がDjango REST Frameworkのアーキテクチャになります。ファイル別にまとめようとするとゴチャっとなってしまうので単純化していますが、大体こんな感じで捉えておくと良いと思います。一部具体的なサービス名が書かれていますが今回はそれを利用するという意図で書いています。今回は「Webサーバー」とそこで動くプロジェクトの部分をNext.jsとVercelが担うという認識で大丈夫です。 HTTPメソッド別には下のような流れです。上図では便宜上、左右両矢印を使用していますが、GETorPOST、リクエストorレスポンスで使用しない部分もあるためめ、上図を参考にしつつ詳しくは以下のメソッドごとの説明をご確認ください。なお、「シリアライズ・デシリアライズ」の説明は【Part 2】で説明します。

  • GETメソッド
    1. クライアントから対象のエンドポイントに対して、GETメソッドでHTTPリクエストを送信→
    2. WebサーバがクライアントからのHTTPリクエストを受信しアプリケーションサーバに転送→
    3. アプリケーションサーバ(今回はgunicorn)がHTTPリクエストを受信し、Django(REST Framework)プロジェクトに転送→
    4. URL dispatcherがリクエストに応じてURLconf(project/urls.pyapp/urls.py)の設定情報に基づき、適切なViewにルーティング→
    5. View(views.py)がデータベースにアクセスしてクエリセット(オブジェクト)を取得→
    6. 取得した戻り値としてのクエリセット(オブジェクト)をView内の記述に基づきシリアライズ(serializers.py)してJSONに変換(※オブジェクトのままだとHTTPレスポンスが生成されないため。→
    7. シリアライズされたデータからHTTPレスポンスが生成されアプリケーションサーバ〜Webサーバを通してクライアントに返送(※HTTPレスポンスは、HTTPリクエスト時に経由したURL dispatcherを経由しない)
  • POSTメソッド等
    1. クライアントから対象のエンドポイントに対して、POSTメソッドでペイロードを含んだ形でHTTPリクエストを送信→
    2. WebサーバがクライアントからのHTTPリクエストを受信しアプリケーションサーバに転送→
    3. アプリケーションサーバ(今回はgunicorn)がHTTPリクエストを受信し、Django(REST Framework)プロジェクトに転送→
    4. URL dispatcherがリクエストに応じてURLconf(project/urls.pyapp/urls.py)の設定情報に基づき、適切なViewにルーティング→
    5. View(views.py)内でリクエストデータをデシリアライズ(serializers.py)してオブジェクトに変換(※オブジェクトのままだとデータベースが取り扱えないため)→
    6. オブジェクトをもとにレコード作成→
    7. オブジェクトをシリアライズ(serializers.py)してJSONに変換(※オブジェクトのままだとHTTPレスポンスが生成されないため)→
    8. シリアライズされたデータからHTTPレスポンスが生成されアプリケーションサーバ〜Webサーバを通してクライアントに返送(※HTTPレスポンスは、HTTPリクエスト時に経由したURL dispatcherを経由しない)

ReactとNext.jsの基礎知識とシステムの理解

Reactの基礎知識

ReactがJavaScriptのライブラリであることについては触れましたが、Next.jsの前提となっているので一旦ここで整理しておきましょう。ここではReactの特徴を4つのポイントで簡単にまとめました。

  1. 宣言的UI

    • 従来のjQueryをはじめとする「命令型UI」では、完成形のUIについて処理の流れを細かく命令に変換し、その命令を上から順番に並べて記述するスタイルなので、どうしてもコードが冗長になってしまいコーディング時と完成形のUIでは乖離があり分かりづらいという欠点がありました。一方で、宣言的UI「UIがどうあるべきか / こんなUIになっていて欲しい」という考えを念頭に完成形のUIをそのまま記述する方式のため、直感的なコードとなり可読性が向上します。
  2. コンポーネント指向

    • Reactでは「コンポーネント指向」の考え方を採用しています。これはコードをまとまり(UIとその動きをまとめた部品=コンポーネント)ごとに小さく分けて開発する考え方です。これにより修正が必要になっても簡単に手を加えることができ、開発済みのコンポーネントはさまざまな場所で再利用しやすいというメリットがあります。今回使用するNext.jsのコードの中でも、例えば画面レイアウトについてはコンポーネント化してあるので、一度作成すれば複数のページで簡単に呼び出すことができ、色や動きを変更したい場合でも数行程度の修正で変更が可能です。
  3. 状態管理

    • Reactにおける「状態管理」とは、アプリケーション内で動的に変化するデータの管理・更新を指します。ここにおけるデータを「状態」「state」と呼びます。Reactのコンポーネント内部ではこのstateというReactの機能を持つことができ、これはユーザーの挙動(ボタンクリック等)に応じて変わります。現行バージョンでは、「React Hooks(フック)」と呼ばれる、クラスを書かずにReactの機能が使える便利な機能があり、例えばuseStateというフックを使うと状態・stateを扱うことができます。下のサンプルコード5行目で早速使ってみました。読み方は4行目の通りです。※React Hooksの他に、より大規模なアプリケーションのための状態管理ライブラリとして「Redux」というものが存在しますが、ここでは省略します。
  4. 仮想DOM

    • そもそも「DOM(Document Object Model)」とはWebページの構造や要素を表現するための仕組みで、通常DOMツリーという木構造で表現されます。JavaScriptによって操作(DOM操作)され、スタイルの変更やイベント登録が可能になります。これをリアルDOMとも呼びますが、Webページの大きさに比例してDOMツリーは肥大化していく上に、jQuery等では更新の度に未更新の箇所まで全て再構築されてしまうため、ブラウザの再描画に時間がかかる問題がありました。そこでReactでは「仮想DOM」というものが使われます。
    • 下のサンプルコードを見てみましょう。11行目・12行目にはボタンがあり、それぞれクリック毎にカウントアップ(+1)とカウントダウン(-1)を実行します。ここで例えばユーザーによるボタンクリック(カウントアップ)が実行されたとしましょう。そうすると、5行目に記述の通りコンポーネントの状態・stateが変更(+1)されますが、その後実際のDOM書き替えの前に新しく仮想DOMが構築され、前回の仮想DOMと比較された上で差分だけが計算されます。これにより更新箇所があった場合は差分を比較して、差分がある部分のみ通常のDOMに反映させ再描画を行うという流れになり、効率的に再描画ができるのです。このコードの場合、ボタンクリック前後で8行目のcount変数({count})の数字以外に変更される部分がないので、修正箇所が極めて限定的で素早い再描画が期待できます。ちなみにjQueryではこのstateがないため、特定のDOM要素の属性や内容を直接操作する必要があります。

他にもReactの特徴は色々とありますが、上で挙げた4点が有機的に絡み合うことでReactの基礎が成り立っています。

Next.jsの基礎知識

Next.jsは冒頭の説明通り、Reactベースの人気のあるWebアプリケーションフレームワークです。ReactベースなのでNext.jsのコードを実際に見てみるとReactでよく使われるモジュールや書き方もたくさん見つかるとは思いますが、ここではNext.jsの特徴的な機能を3点まとめてみました。

  1. サーバーサイドレンダリング(Server-side rendering:SSR)のサポート
    • Reactとの大きな違いの一つとして、Reactでは全てのコンテンツをクライアントサイド(ブラウザ)でレンダリング( 「Client-side rendering:CSR」)する点にあります。CSRは初回読み込み後ページ遷移の度にリクエストが発生せず必要最小限のデータのみ読み込むため画面遷移が滑らかである点がUXの観点からメリットとされていますが、その反面初回にJavaScriptも同時に読み込むため初回表示に時間がかかりSEOに向かないというデメリットが挙げられます。一方で、下の表の通りNext.jsであれば、ページ別に4つあるレンダリング手法の中から好きなものに切り替えることができます。※Next.js公式ではSSRよりもSSRが推奨されています。
4種類のレンダリング手法
手法 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・動画投稿サービス ニュースサイト・ブログ ダッシュボード
  1. ファイルベースルーティング

    • Reactで画面遷移を実装する場合react-router-domというライブラリを使用しますが、Next.jsでは/pagesディレクトリ以下にファイルを作成すると、そのファイル名がそのままURLとなります。例えば/pages/about.jsファイルを作成すると、aboutがそのままURLとなるイメージです。他にも/pagesディレクトリ直下のindex.jsファイルにページを構成する記述をするとそれがそのままトップページとなり、/pagesディレクトリの下にサブディレクトリを作成すると、index.jsファイルがそのままディレクトリ名のURLとなります。
    • また、Next.jsでは「ダイナミックルーティング」もサポートしています。これは通常任意の/pagesディレクトリ下のサブディレクトリ内で作成する1つのファイル(/pages/sub/[slug].js/pages/sub/[id].js)を複数のURLに紐付ける手法です。これにより、1つだけファイルを作成すれば同じ形式を持つデータを当てはめるだけで大量のページを作成できるため、効率よく統一感のあるページを作成します。ブログ作成等に利用されます。
  2. ファストリフレッシュ

    • 「ファストリフレッシュ」開発時にソースコードを変更した場合、状態・stateを維持した状態で変更箇所のみ再描画しブラウザの画面がリロードされる機能です。例えば、上のReactの部分でカウントアップ・カウントダウンの説明をしましたが、Reactの場合リロードするとこれらの値は初期値に戻ってしまうのですが、ファストリフレッシュを利用すればこの値がそのまま保持されるので、開発者にとっては開発体験が向上します。

その他ライブラリの基礎知識

MUIの基礎知識

今回のブログ作成にはMUI(旧Material-UI)を使用しています。MUIとはReact用のコンポーネントライブラリでGoogleが提唱する「Material Design」というデザイン体系のガイドラインをベースに作られています。MUIを使うことで以下のようなメリットがあります。

  1. 統一感のあるデザイン
    • MUIではボタン、テキストフィールド、ナビゲーション、テーブル等様々なコンポーネントを利用できますが、前述の通りMaterial Designに則ったコンポーネントのため、いずれも統一感があります。つまり、MUIコンポーネント詰め詰めのUIにしても(情報量は多くなりますが)それっぽいWebアプリが出来上がるわけです。
  2. カスタマイズ
    • MUIは統一感のであるデザインではありますが、デフォルトでは青系統の色味になっていると思います。しかし、できれば自分が作りたいWebアプリのコンセプトに合わせて色の系統を調整したいですよね。そのようなカスタマイズもMUIでは簡単にできてしまいます。
  3. レスポンシブ対応
    • スクラッチでWebアプリのデザインパターンを作るのは、特にレスポンシブの面でかなり骨が折れますよね。わたしも時々アバラ逝っちゃいます。それにメンテナンスもかなり苦労することでしょう。。1. の統一感のあるデザインと一部重複しますが、MUIならレスポンシブ対応もお手のものです。コンポーネントを埋め込んで文字を変えるだけでもそこそこに調整してくれるので、初見でも扱いやすくできています。

Markdownの基礎知識

最後に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プロジェクトの開発に入っていきます。

参考


記事をシェアする




記事一覧へ