Blazor WebAssemblyで新規の業務システムを開発している話
背景
bitflyerの12/22のアドベンドカレンダーは、「Blazor WebAssemblyを用いた新規の業務システムの開発(現在進行中)」の話をしたいと思います。Blazor WebAssemblyを検討している人や現在開発中の方の手助けになればと思います。
bitFlyerのバックエンドの言語は基本的にC#で、クラウドはAzureを使用しています。そのため、他のクラウドを使用している場合は、一部異なる可能性があります。
また、検討および開発を2022年4月下旬に開始したため、最新と多少異なる可能性があります。
bitFlyerでのバックエンドの開発環境は、
- 言語:C#
- フレームワーク:.Net Framework 4.7.2, .Net Core3.1, .Net 5, .Net 6
- インフラ:Azure
(参照:https://bitflyer.com/ja-jp/recruit)
となっています。(この記事で必要なもののみ記載)
弊社には内製の業務システムが複数ありますか、最も使用されており、最も開発が行われている業務システムはC# + Web Formsで作られています。
Web Forms:https://learn.microsoft.com/ja-jp/aspnet/web-forms/what-is-web-forms
個人的にWeb Formsは開発がしづらいため触りたくない(自分だけではないはず!)。
また、技術的に古いため、セキュリティ的に移行すべきではないかと思いました。
そこで、新規の業務システムを提案しました。
その際に、
- どのように開発環境などを選んだ
- 開発中にぶつかった壁や問題など
などを説明します。
開発環境の選定
既定の開発環境
この3つは、社内の方針から、既定となっていました。
- 言語:C#
- インフラ:Azure
- 認証:Azure Active Directory [https://learn.microsoft.com/ja-jp/azure/active-directory/fundamentals/active-directory-whatis] (以後、AAD)
新システムの方針
新規のシステムの開発・開発環境の選定にあたり、以下のことを重要視しました。
- 開発や運用を可能な限り属人化しない
- 学習コストが低い
- 社内システムであるため、フロントエンドの開発もバックエンドエンジニアのみで行うことを可能にする
以上のことから、Webフレームワークとして、Blazorを選択しました。次のサーバーサイドやフロントエンドの選定の説明をします。
サーバーサイド関連
Webフレームワーク
C#のWebフレームワークの選択肢として、
- .Net Framework 4.8
- .Net Core 3.1(もうすぐサーポートが切れる)
- .Net 6
が挙げられますが、最新のものとして.Net 6を選択しました。
フロントエンド関連
Blazor Server or Blazor WebAssembly
Blazorには、ServerとWebAssemblyの2つがあり、Blazor WebAssemblyを選択しました。
その理由としては、
- Blazor WebAssemblyのほうが、高速である
- 標準でcsprojが分割されており、必要に応じてcsprojを分けることが可能である
ためです。
ClinetサイドとServerサイドの連携がAPIであるため、開発工数を増やしてしまう点がデメリットです。
ちなみにですが、WebAssemblyのことを、wasmと省略している場合が多いです。何か調べるときには、両方のパターンを試すといいかもしれません。
https://learn.microsoft.com/ja-jp/aspnet/core/blazor/hosting-models?view=aspnetcore-7.0#which-blazor-hosting-model-should-i-choose
UI Componentの選定
Blazor WebAssemblyのフロントエンドの開発を簡潔にするUI Componentの選定です。
(UI Componentの選定 Confluence参照)
BlazorのUI Componentとしては以下のようなものがあります。
- MatBlazor
- Ant Design Blazor
- Radzen
- Syncfusion
- Skclusive.Material.Component
- Blazorise
- BlazorStrap
- PanoramicData.Blazor
- MudBlazor
- Element Blazor
- Blazored
参照
選定基準
- リリース頻度
- 最近更新が行われていないものは除外
- 定期的にリリースされているもの
- リリースバージョン
- 1.0.0以上のもの
- Githubのスター数
- 学習・開発コスト,開発のしやすいさ
- コンポーネント数・ドキュメントの内容
- 費用面は要相談
リリース頻度 | リリースバージョン | Githubのスター数 | 学習・開発コスト 開発のしやすいさ | コンポーネント数 ドキュメントの内容 | 費用 | |
---|---|---|---|---|---|---|
MatBlazor | × 2019/9/10で止まっている | 〇 1.7.2.3 | ◎ 2.7k | ◎ | ◎ | ?? |
Ant Design Blazor | ◎ | × v0.10.7 | ◎ 4.2k | ◎ | ◎ | ◎ |
Radzen | ◎ | ◎ 3.18.11 | 1.7k | 〇 | ◎ | 〇 条件あり |
Syncfusion | ◎ | ◎ | ?? | ◎ | ◎ | × |
Skclusive.Material.Component | × 2020/12/6 | ◎ 5.2.0 | × 375 | ?? | ?? | 〇 |
Blazorise | × 2020/4/18 | × 0.9.0 | ◎ ×2.3k | ?? | ?? | ◎ |
BlazorStrap | ◎ | ◎ | × | ?? | ?? | ◎ |
PanoramicData.Blazor | × | × | × | - | - | - |
MudBlazor | ◎ 2022/5/4 | ◎ 6.0.10 | ◎ 3.2k | ?? | 〇 | - |
Element Blazor | - | - | × | - | - | - |
Blazored | - | - | × | - | - | - |
総合的にみると、以下の3つに絞りました。
- Radzen
- Syncfusion
- MudBlazor
Syncfusionは費用面($2,495/1Develper/1year)に問題があり、MudBlazorはドキュメントが不十分である(2022/04時点)ため、Radzenを選びました。
- Web Page
- Free Blazor Components | 70+ controls by Radzen
- Online Demo
- Github
インフラ
Blazor WebAssemblyを乗せるリソースですが、
- 社内システム
- 利用者数の増減はそれほど大きくない
- SREの知見が多い
ということで、App Service(Windows)を選択しました。
認証
Blazor WebAssembly AAD認証
Blazor WebAssemblyの新規プロジェクト作成時に、認証を選ぶことができます。その際に、AADを選択するか、AADの登録を行った後、コマンドを使うことで簡単に新規プロジェクトを作成することができます。
注意点としては、AADのページの”アプリの登録”からクライアントサイド用とサーバーサイド用の2つを新規登録する必要があります。
詳細な手順は以下のページを参照してください。
AADにおける権限設定
AADでは、これら3つを組み合わせて権限を設定します。
- ロール
- ユーザー
- グループ
簡単な図で表すと以下のようになります。
1つのシステムに対し複数のグループを作成し、そこにユーザーとロールを割り振ります。
開発中にぶつかった壁や問題など
認証情報の保存先
Blazor Webassemblyの認証情報の保存先(デフォルト)はsession storageとなっています。また、クライアント側の設定でlocal storageに変更することができます。しかし、SessionStorageはXSSに弱いという問題点があります。
この点をMicrosoftに問い合わせたところ、Blazor Webassemblyのライブラリでは、認証情報をcookieに保存することができないという回答を得ました。
クエリの長さ制限
クライアントサイドからサーバーサイドのAPIを呼ぶ際に、デフォルトでクエリの最大長さが決まっています。それを超えるとエラーが出るため、クエリの最大長さを大きくする必要があります。App Service(Windows)を使用しているため、Web.configで更新することができ、以下のようになります。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxQueryString="10000" />
</requestFiltering>
</security>
</system.webServer>
</location>
</configuration>
appsettings.XXXXX.json
サーバーサイドおよびクライアントサイド両方に、以下の4種類のappsettings.jsonがあります。
- appsettings.json
- appsettings.development.json
- appsettings.stating.json
- appsettings.production.json
どの環境なのかをわける指標がASPNETCORE_ENVIRONMENT であり、App Serviceに設定する必要があります。また、サーバーサイドおよびクライアントサイド共通で設定することが可能です。
アクセストークン
サーバーサイドのAPIではアクセストークンによる認証で動作しています。アクセス トークンの既定の有効期間には、60 分から 90 分 (平均 75 分) の範囲のランダムな値が割り当てられます。
Blazor WebAssembly画面にあるログアウトボタンを押しても、アクセストークンは無効になりません。
採用
現在、bitFlyerではエンジニアを募集中です。皆さんの応募を待っています!
また、個人的な話ですが、Wantedlyでインタビューを受けました。そちらの記事も読んでいただければ幸いです。
Discussion