@kawasima
- GitHub: https://github.com/kawasima
- Qiita: https://qiita.com/kawasima
- SlideShare: http://www.slideshare.net
- Twitter: @kawasima
テーマ「越境」ということですが、
Webアーキテクチャのボーダーが崩れてみな越境の必要がある
というお話をします。
私 そこそこ大規模SIer の立場なので、
多分ほとんどの人にとって、
「対岸の変化」ではないはず。
- フロントエンド vs バックエンド
- サーバサイド vs クライアントサイド
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=14
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=15
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=16
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=17
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=18
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=19
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=20
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=21
https://speakerdeck.com/koichik/isomorphic-survival-guide/?slide=22
サーバサイドでHTMLをレンダリングする時代に終わりが来たようだ。
- レガシーシステムにAPIを生やしはじめた。(FinTechなどのxTechブームはここを変えた)
- APIを使って多くのアプリケーションを速く作るニーズ。 (PoCへの投資)
- レガシーブラウザの死 (IE11よ…)
- プログラマとデザイナの分業
- ビューコンポーネントの再利用 (動的な側面を含むこともできる)
FinTechもMicroservicesもただの触媒にすぎない。 限界はそこかしこですでに来ている。
- エラーになった項目をフォーム再表示
- 薄い機能のテンプレートじゃないとべザインとロジックの分離できない
- 薄い機能のテンプレートだとコントローラにビューロジック混入しがち
- 戻るボタンの実装
- 結局、ブラウザ上での動的な挙動はJavaScriptで実装せざるを得ない
1人の開発者で1画面完璧に実装するのは難易度高い
- HTMLとCSSに関する基礎知識
- HTTPの仕様
- クライアント/サーバ両方のセキュリティリスクと対策
- ブラウザの違いについての知識
- 効率的なSQLの書き方
- セッション管理の設計と実装
ひとりのプログラマが全部できなきゃいけない。
できて当たり前という風潮 😂
- APIサーバ
- BFF
- ブラウザ/ネイティブのフロントエンドアプリ
「今までHTML返してたところ、JSON返すようにするだけでしょ」は火傷する
- 互換性
- 拡張性
- エラーハンドリング
- ……
https://restful-api-guidelines-ja.netlify.com/
- 任意のフィールドのみ追加して、必須のフィールドは追加してはならない。
- フィールドの意味は決して変えてはならない (例えばcustomer-numberをcustomer-idに変更することは、両者はカスタマの一意キーとしての意味は異なるのでNG)
- サーバサイドのビジネスロジックでバリデーションしなきゃいけないような(複雑な)制約をもつ入力フィールド。バリデーションロジックは、より厳しくなる方向には変更してはいけません。すべての制約はdescriptionに明示します。
- 入力パラメータとして使われる列挙型の要素は、サーバが古い値も受け付けて正しくハンドリングできる場合のみ減らすことができる。出力パラメータとして使われる列挙型はいつでも減らすことはできる。
- 出力パラメータとして使われる列挙型は、クライアントがハンドリングできないかもしれないので追加してはならない。入力パラメータとして使われる列挙型はいつでも追加できる。
- 出力パラメータととして使用され将来の拡張も考えておきたい場合は、x-extensible-enumを使う。 明示的に値を上限なしリストと定義し、クライアントは新しい値には依存しない設計をしなければならない。
- URLを変更するときはリダイレクションをサポートする (301 Moved Permanently).
そもそもサーバサイドでセッションとしてもつもの
- 入力/確認/完了までの入力データ
- 検索条件 (更新ユースケースから一覧へ戻ったとき用)
- 閲覧履歴
- 認証状態 (ログインセッション)
認証状態だけなんとかすれば良さそう
pure HTMLに近いテンプレートエンジンを使っても十分には解決しえなかった
- コンポーネント指向
プログラマは思考回路がコンポーネント指向なので、
デザインも同様にコンポーネント化する。
const SlidePreviewList = (props) => (
<Wrapper height={props.height}>
{props.slide.pages.map((page, index) => renderSlidePreview(page, index, props))}
<SlidePreview>
<SlideContainer>
<NewSlideButton onClick={props.onPressNewSlide} type="button">+</NewSlideButton>
</SlideContainer>
</SlidePreview>
</Wrapper>)
特にプログラマがデザインレイヤまで作ると…
だいたいmargin, paddingレスデザインになる (Bootstrap使ってもダサい…レイアウトが詰まる…)
→ コンポーネントの組合せ単位で考えることで解消
コンポーネントにスタイルをカプセル化する。
const SlideContent = styled.div`
${props => props.center && 'text-align: center;' }
height: 100%;
padding: 1em 4em 1em 4em;
img {
max-width: 100%;
}
`
Atomic Designのコンポーネントそれぞれで、適切なマージン・パディングを考えられる。
- Atom: 他コンポーネントに依存しない
- Molecules: 組合せ可。AtomでもMoleculeでもないもの。
- Organisms: 他のページでも再利用できる可能性のあるもの。
- Template: Organisims以下のコンポーネントを配置してpropsを渡すだけ。レイアウトに関する責務のみ
- Pages: Redux/Fluxとの接続のみ
storybook自体には賛否両論あるが、コンポーネントのカタログ化重要
- ルーティング
- クライアントステートの設計
- フロントエンドのロジック
- APIの呼び出しの最適化
タブを閉じたり、リロードしたときにデータが失われないように。
- Cookie
- Local Storage
- Session Storage
- Indexed DB
- React Componentのレイヤで非同期イベントハンドリングするとたちまちコードが複雑化する
- 個別のComponentでイベント処理せず、sagaが一手に担う。
- そうすることでReact ComponentをSimpleに保ち、分業が可能にできる。
export function* onSlideLoaded(action) {
const res = yield axios.get(action.payload.url, {
responseType: 'text'
})
const pages = res.data.split(/[\n\r]-{4,}[\n\r]/m)
yield put(Actions.setEntirePages({ pages, current: 0}))
}
- ルーティング
- 認証領域の保護
- フロー制御 (戻るボタン/バリデーションエラー時のコントローラメソッド)
- メッセージ文言
- セッション管理
- HTMLレンダリング
- ビューロジック
- フォーマッティング
- ……
あなたはどこに向かう?