作記録

記憶代わり

システム開発におけるモデリング

現状、僕が関わった開発では、モデリングをする開発、しない開発があった。

これらの開発をした経験上では、モデリングをしない開発は、画面デザインを根拠としてシステム設計を行っている傾向がある。
画面デザインを先に作り、それに従ってDB設計を行い、そのDBが持つデータを集めたクラスを設計する。

こういった設計を行うと、とにかく知識が付かない。
データ構造だけに意識がいき、同じような記述や、意味の分からない名前などが大量に作られる。

では、モデリングをする開発はそういった事が全く起こらないかと言うとそうでもない。

そもそもモデリングを行うには、専門的な知識とその専門的な知識を理解するための前提の基本知識を必要とする。
だからそういった知識が少ないと変なモデルになる。
だからこのモデルを改良し続けなければいけない。

Instagram Graph APIにSpring Bootアプリケーションからリクエストする

概要

大まかに下記の手順を踏むことで Instagram Graph API にリクエストする。 1. Spring Security OAuth2 Clientを利用してFacobookにログイン 2. ログインした状況で、Instagram Graph API にリクエストを行うAccess Token を取得する 3. Access Token を利用して Instagram Graph API にリクエストする

公式document

主な使用技術とversion

  • OpenJDKI 17.0.2
  • Spring Boot 2.7.1
  • Spring Security 5.7.2
  • Spring Security OAuth2 Client 5.7.2

前提知識

https://www.youtube.com/watch?v=PKPj_MmLq5E

上記の OAuth & OIDC 入門編 by #authlete という Authleteさんの動画が、OAuth2.0とOpenID Connectを理解する上で、とてつもなく分かりやすい。
なので見て理解しておくと、Spring SecurityのOAuth2 Loginの機能が何を裏でしているのかが分かって良いと思う。

前提

下記の状態である事を前提とする。

  • 自身のFacebookアカウントがある。
  • 自身のInstagramアカウントがあり、それはビジネスアカウントに設定している。

1. FacebookページとInstagramビジネスアカウントを紐づける

Facebookページとは、個人の情報が記載されるFacebookのアカウントとは別に、ビジネスなどの目的でFacebook上に作られるアカウントを指すもよう。

1-1. 自身のInstagramビジネスアカウントの プロフィールを編集 ボタンを押下して編集画面に遷移する

1-2. 編集画面のページの行の リンクまたは作成 を押下して Facebookページにリンク モーダルを表示させる。

1-3. Facebookページをリンクする

  • InstagramビジネスアカウントとリンクさせたいFacebookページが無ければ Facebookページを作成 を押下してFacebookページを作成する。作成が完了するとリンクが完了する。
  • 既にInstagramビジネスアカウントとリンクさせたいFacebookページがあれば 既存ページをリンク を押下する。押下するとリンクが完了する。

2. Meta for Developers

2-1. 自身のFacebookアカウントとしてFacebookにログインする

https://developers.facebook.com/products/facebook-login/?locale=ja_JP

上記のページの右上のログインからFacebookにログインする。

2-2. マイアプリページに遷移する

上記でログイン後、ヘッダーに マイアプリ というリンク先が表示されるので、押下して遷移する。

2-3. アプリを作成 ボタンを押下してアプリタイプ選択画面に遷移する

2-4. 適切なアプリタイプを選択して、次へを押下して基本情報入力画面に遷移する。

2-5. 基本情報を入力して、アプリ作成 ボタンを押下してMeta for Developers のダッシュボードに遷移する

アプリ作成 ボタンを押下するとFacebookアカウントのパスワードを求められるので入力すると、ダッシュボードに遷移する。
これによりMeta for Developersにアプリを作成出来る。

3. 開発モード

3-1. テストアプリを作成 ボタンを押下する

テストアプリを作成 ボタンを押下すると、テストアプリを作成 モーダルが表示される。

3-2. テストアプリ名を入力して、テストアプリを作成 ボタンを押下する

テストアプリを作成 ボタンを押下すると、パスワードをもう一度入力してください というモーダルが表示されるのでFacebookアカウントのパスワードを入力して送信を押下する。
これによりMeta for Developersに上記のテストアプリの作成が出来る。
このテストアプリでは、アプリは開発モードとなり、localhostによるAPIの開発が出来るようになる。

4. Spring Boot アプリケーションの構築

4-1. IntelliJ IDEAからNew Projectを作成する

IntelliJ IDEAのSpring Initializer からNew Projectを作成する。
上記のように依存性を含めて create ボタンを押下すると、下記のような依存性を定義されたbuild.gradleファイルが含まれたプロジェクトが作られる。
https://github.com/sakuoden/instagram-graph-api-sample/blob/main/build.gradle#L15-L26

4-2. Security Configの設定を定義する

Spring Security の OAuth2 ログイン機能(Spring Boot Starter OAuth2 Client に依存している)を使うことで、OAuth2で定義されている認可コードフローを、自身で実装せずに達成してくれる。
ログイン機能を使う設定は下記URLの通り。
https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/java/sample/infrastructure/config/SecurityConfig.java

上記の設定により - ログイン方法をOAuth2ログイン機能にしている。 - /login(ログインページ)と/css/**, /favicon.ico(リソース関連)以外へのリクエストは、全て認証されなければならない設定にしてある。

4-3. application.propertiesに必要な値を定義する

Spring Security の OAuth2 ログイン機能(Spring Boot Starter OAuth2 Client に依存している)に必要な値を定義する。 その設定は下記の通り
https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/resources/application.properties

各キーと値について説明
キー 説明
spring.security.oauth2.client.registration.facebook.client-id 上記2で作成したテストアプリの アプリID を記述する。上記例のapplication.propertiesでは実際の値を環境変数に定義している。Meta for DevelopersのFacebookアプリダッシュボードの 設定 -> ベーシック に記載されている。
spring.security.oauth2.client.registration.facebook.client-secret 上記2で作成したテストアプリを app secret を記述する。上記例のapplication.propertiesでは実際の値を環境変数に定義している。Meta for DevelopersのFacebookアプリダッシュボードの 設定 -> ベーシック に記載されている。
spring.security.oauth2.client.registration.facebook.scope AccessTokenが許可する範囲を記述する。記述する内容は、スタートガイド2. Facebookログインを実装する に記載されている。
spring.security.oauth2.client.provider.facebook.authorization-uri OAuth2.0の認可エンドポイントを記述する。これを記述しないとSpring Bootが設定しているデフォルトの認可エンドポイントにリクエストを行い、結果としてversion2.8くらいのエンドポイントにリクエストされる。この値は執筆時点での最新versionである。
spring.security.oauth2.client.provider.facebook.token-uri OAuth2.0のトークンエンドポイントを記述する。これを記述しないとSpring Bootが設定しているデフォルトの認可エンドポイントにリクエストを行い、結果としてversion2.8くらいのエンドポイントにリクエストされる。この値は執筆時点での最新versionである
spring.security.oauth2.client.provider.facebook.user-info-uri OpenID ConnectのUserInfo Endpointにリクエストされるuriを記述する。これは定義しなくてもデフォルトの設定で良さそうだが、念の為記述している。

4-4. ログインしたUserのアクセストークンを取得するコンポーネントを作成する

https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/java/sample/infrastructure/security/LoginContext.java

参考記事

4-5. Instagram Graph APIにリクエストするクライアントを作成する

https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/java/sample/infrastructure/api/InstagramGraphApiClient.java

4-6. 投稿一覧を取得するサービスを作成する

https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/java/sample/application/InstagramService.java

4-7. Facebookログインをする画面とControllerを作成する

Controller

https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/java/sample/presentation/LoginController.java
OAuth2AuthorizationRequestRedirectFilterに定義されているDEFAULT_AUTHORIZATION_REQUEST_BASE_URIを利用する。
このURIにリクエストをすると、Spring SecurityがFacebookの認可エンドポイントにリクエストを送る。

HTML

https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/resources/templates/login.html

4-8. Instagramの投稿一覧を表示する画面とControllerを作成する

Controller

https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/java/sample/presentation/HomeController.java
上記4-6で作成したInstagramServiceを利用して投稿一覧オブジェクトを取得する。

HTML

https://github.com/sakuoden/instagram-graph-api-sample/blob/main/src/main/resources/templates/home.html

複数アプリケーション + 単体DBの運用パターン

前提

マイクロサービスのような言い方があるのかもしれないけど、マイクロサービスとは何かを明確に言葉に出来ないので分かっている範囲の言葉を使う。
複数アプリケーションが単体のDBの情報を利用しなければいけない場合に現状試しているパターンを列挙する。

図の例で使う言葉の定義

単体DB(とそれを操作するアプリケーション)

言葉 定義
利用者DB 複数アプリケーションを利用する者(利用者)のアイデンティティ(識別IDや名称)が記録されるDB。タイトルや上記前提に記載の単体のDBである。
利用者アプリケーション 利用者DBを操作などを行うアプリケーション。

複数アプリケーション(とそのリソースやイベントを記録するDB)

言葉 定義
予約DB 上記の利用者の予約を記録するDB。
予約アプリケーション 予約DBの操作などを行うアプリケーション。
チャットDB 上記の利用者のチャットを記録するDB。
チャットアプリケーション チャットDBの操作などを行うアプリケーション。

パターン

APIパターン

複数アプリケーションが利用者の情報が必要なときに、利用者アプリケーションに用意されたAPIにリクエストを送る。
予約DBは利用者の識別ID以外の情報には関与しない。
デメリットは利用者の情報と予約アプリケーションの情報を組み合わせた情報を取得する際に、複数回APIリクエストをしなければいけない事がある。その場合は、下記のパターンを検討する。

DB複製パターン

既に利用者DBがある場合は事前に、利用者DBのテーブルの利用者情報を複製しておく。
以降は、利用者アプリケーションに利用者情報の変更(新規登録)のイベントが起こる場合に、その変更イベントと変更内容を複数のアプリケーションのAPIに通知する。
通知を受け取ったらその内容に応じて、自身のDBのテーブルに記録する。

IntelliJ IDEA と Spring Boot と Thymeleaf で Tailwind CSS を使う

前提

開発中のHTMLとCSSの確認は、IntelliJ IDEA で Controllキー + D を押して「ビルド + Spring Boot Application起動」してローカル環境でWEBブラウザを目視する事を前提としている。
(HTML または CSS を変更する事で自動でビルド + 起動はしない。)

Version

手順

1. Tailwind CSS をインストールする

$ yarn add --dev tailwindcss

2. tailwind.config.js を生成する

$ npx tailwindcss init

3. ./tailwind.config.js に下記を記述する

module.exports = {
  content: ["./src/**/*.{html,js}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

4. ./src/main/resources/static/css 配下に tailwind/input.css を作成する

5. ./src/main/resources/static/css/tailwind/input.css に下記を記述する

@tailwind base;
@tailwind components;
@tailwind utilities;

5-1. 上記5の @tailwind に赤い警告が出たら...
  1. IntelliJ Idea の Preference を開く
  2. Plugin で Tailwind CSS をinstallする

6. ./src/main/resources/static/css/tailwind 配下に generator.sh を作成する。

7. ./src/main/resources/static/css/tailwind/generator.sh に下記を記述する

#!/bin/sh
CURRENT_DIRECTORY=`dirname $0`
npx tailwindcss -i "$CURRENT_DIRECTORY/input.css" -o "$CURRENT_DIRECTORY/tailwind.css"

8. ./generator.sh に実行権限を付与する

$ chmod 744 generator.sh

9. IntelliJ IDEA の Edit Configurations を開く

10. Modify options を開く

11. Add before launch task を押下

12. 「+」を押下

13. Run External tool を押下

14. 「+」を押下

15. 必要事項を入力

・Name

識別する名称
(例)Output Tailwind CSS

・Program

上記7で作成した tailwind.sh ファイルのパスを入力 または 選択する。

・Working directory

tailwind.config.jsファイルがあるディレクトリ(この記事の場合は、プロジェクトのルート)を指定する。
これは、 npx tailwindcsstailwind.config.js のパスを指定しなければいけない。
指定しない場合は、デフォルトで current directory が指定される。
その為、 tailwind.config.js ファイルがあるディレクトリを指定する。

16. 起動順序を入れ替えてOKボタンを押す

1番目に External tool External Tools/Output Tailwind CSS
2番目に Build

17. HTMLを作成して生成した tailwind.css をダウンロードするように記述する

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <link th:href="@{~/css/tailwind.css}" rel="stylesheet">
</head>
<body>
<h1 class="text-3xl underline text-red-600">テスト</h1>
</body>
</html>

個人的なCSSフレームワークの使い分け

以下、全て個人的な使い分けと感想。

画面設計書をHTMLとCSSで書く場合、 Buluma を使うと良さそう。
画面設計書としてのHTMLとCSSの目的は、WEBブラウザで実際のデータの動きや画面の本質的な動きを自分やデザイナーやお客さんに見せる事である。
よって、あまりデザインにこだわらず、綺麗なレイアウトを簡単に作れそうな Buluma が良さそう。
MVP.css だとデザインが微妙すぎる感がある。

Bulma: Free, open source, and modern CSS framework based on Flexbox

画面設計書からデザインなどが完成した後は、Tailwind CSS を使うと良さそう。
この時点でのHTMLとCSSの目的は、WEBブラウザにユーザーのインターフェースを作成する事である。
デザイナーがデザインしたユーザーインターフェースになるように細かいCSSの設定が必要になる。
ここでクラス名などを独自で作っていると、他のプロジェクトなどをやるとクラス名からスタイルのイメージが湧かなくなる。
一方でCSSフレームワークを使うと、細かいデザインがしにくくなる。
こうった事情を鑑みた結果、Tailwind CSS が良さそう。

Tailwind CSS - Rapidly build modern websites without ever leaving your HTML.