5
0

Next.jsで実現するオニオンアーキテクチャ (5) - Presentation

Last updated at Posted at 2023-12-24

記事におけるNext.jsは、v13以降のApp Router (Server Components)を用いる前提での説明となります。
Pages Routerを用いている場合は、適宜Pages Routerでの書き方として読み替えてください。

この記事は何

最近Next.jsでウェブアプリケーションを作ることが多いのですが、
その時にオニオンアーキテクチャを採用してアプリケーションを作ることが多く、型も固まってきたので数回の記事にわたり紹介をしていきたいと思っています。

前回は

でInfrastructureについて紹介しました。

今回はappディレクトリ内で実装していくPresentaionについて説明をしていきます。

Presentationとは

Presentationとは、レイヤーとしては 最も外側に位置し、ユーザーとのインテラクションをとるレイヤーになります。
このレイヤーでは、以下のようなことを行なっていきます。

  • UIの描画(処理の出力)
  • ユーザーからの入力の受付

これを実現するために、基本的にPresentationではInfrastructureやApplication Serviceへのアクセスを行いながらデータの取得や、ユーザーの入力を元にした処理の実行を行なっていきます。

Next.jsにおけるPresentationの実行

この章まで色々な処理について紹介してきましたが、ここまでほぼNext.js特有の話はしてきていないと思います。
正直言うと、Presentation以外のレイヤーの処理はNext.js以外の環境でも同じように適用することができます。
Next.jsはこのPresentaionを実装するにあたって必要になってきます。

Next.js v13から、AppRouterという形でServer Componentsを用いることが可能になりました。
このServer Componentsが前項で紹介したようなベージの描画時の処理を実装していく部分になります。
また、v14からはServer Actionsも安定版になったため、ユーザーからの入力を元にした処理はAPIを実装せずともServer Actionsで実装できるようになっています。

Server Components、Server Actionsについては以下をご覧ください。

実装例

今回は例として、以下のようなページを実装してみます。

  • URLのuuidの値をもとに、そのuuidを持つユーザーが持っている通貨一覧を表示する
  • フォームでuuidと通貨の情報を入力すると、送金が行える
app/users/[uuid]/page.tsx
import { UserRepository } from '~/infrastructures/UserRepository';
import { UserApplicationService } from '~/applications/UserApplicationService';
import { sendNotification } from '~/utils/sendNotification'
import { Money } from '~/models/users/Money';
import { notFound } from 'next/navigation';

const sendMoney = (formData: FormData): Promise<void> => {
  "use server";

  const sendUserUuid = formData.get("sendUserUuid") as string;
  const receiveUserUuid = formData.get("receiveUserUuid") as string;
  const amount = Number(formData.get("amount") as string);
  const currencyType = formData.get("currencyType") as string;
  const money = new Money({ amount, currencyType });
  const userRepository = new UserRepository();
  const userApplicationService = new UserApplicationService({ userRepository });

  userRepository.sendMoney({
    sendUserUuid,
    receiveUserUuid,
    money,
    sendNotification
  })
}

export const Page = ({ params }: { params: { uuid: string } }) => {
  const userRepository = new UserRepository();
  const userApplicationService = new UserApplicationService({ userRepository });
  const user = userRepository.findByUuid(params.uuid);

  if(!user) return notFound();

  return(
    <div>
      <div>
        {user.getMonies().map((money) => (
          <li key={money.currencyType}>
            {money.amount} {money.currencyType}
          </li>
        ))}
      </div>
      <div>
        <form onSubmit={sendMoney}>
          <input
            type="hidden"
            name="sendUserUuid"
            value={user.uuid}
          />
          <input
            type="text"
            name="receiveUserUuid"
            required
          />
          <input
            type="number"
            name="amount"
            required
          />
          <input
            type="text"
            name="currencyType"
            required
          />
          <button type="submit">送金</button>
        </form>
      </div>
    </div>
  )
}

最後に

今回はNext.jsを用いたPresentationの実装についての紹介を行いました。
これでNext.jsでのオニオンアーキテクチャの実装の紹介は全てになります。
ここまで読んでいただきありがとうございました。

今までの記事

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0