2017年5月18日

Node, express, nginx で動くWebサイトへのファイルアップロードでサイズ超過エラーが出る時の対策

Node/Express.js で作ったWebアプリケーションをテストしていて、CSVファイルのアップロード時に一定のファイルサイズを超えると「413 Request Entity Too Large」というエラーになる事に気付きました。


調べた結果、

  1. ExpressのbodyParserミドルウェア
  2. MultiPartフォームデータの処理を簡単にしてくれるミドルウェアのMulter
  3. そしてリバースプロキシとして使っているNginx 

の3箇所で許可するファイルサイズの最大値を設定する必要があることが分かりました。


1. Expressの設定


app.use(bodyParser.json({ limit: '20mb' }));
app.use(bodyParser.urlencoded({ extended: true, limit: '20mb' }));


2. Multerの設定


const upload = multer({
  limits: {
    fileSize: 1024 * 1024 * 20, // 最大20MBまで許可
  }
});



3. Nginxの設定


location / {
proxy_pass http://127.0.0.1:3000;
... (略) ...
client_max_body_size 20M;
}


最初1と2の設定を付けたのに上手く行かなくて、3の設定が必要な事に気付くまでに時間がかかってしまったので、メモしておきます。







 

2017年4月15日

ASP.NET CoreとEntityFrameworkで最速でWeb APIを作るには

ASP.NET Core, EntityFrameworkとVisual Studio Codeを使ってデータベースから情報を取得してJSONで返すWeb APIを作ります。

コードファーストは使わず、既存のデータベースが存在するという前提で作ります。
とりあえず Northwind というサンプルのデータベースが存在すると仮定してコーディングしていますが、データベース名、テーブル名やモデルクラスの内容は適宜手元の環境に合わせて読み替えて下さい。

以下ステップ0から8までに分けましたが、おそらく20分もあれば全部出来ると思います。


ステップ0 - .NET Core SDKとVS Codeをインストール
ステップ1 - プロジェクトを作成する
ステップ2 - 依存パッケージを追加する
ステップ3 - モデルクラスを作成する
ステップ4 - DbContextクラスを作成する
ステップ5 - リポジトリクラスを作成する
ステップ6 - 設定ファイルにDB接続文字列を追加する
ステップ7 - Startupクラスに設定を追加する
ステップ8 - Controllerを作成する




ステップ0 - .NET Core SDKとVS Codeをインストール


下のサイトからインストールして下さい。

https://www.microsoft.com/net/core


VS Codeをインストールした後、C#用の拡張機能をインストールしておいて下さい。



ステップ1 - プロジェクトを作成する


dotnet new mvc --auth None --framework netcoreapp1.1 -o MySampleWeb
cd MySampleWeb
dotnet restore
code .

VS Codeでフォルダを開いて、拡張子が.csのファイルを表示すると2〜3秒後にダイアログが表示されるので、「Yes」をクリックします。


プロジェクトフォルダ直下に.vscodeフォルダが作られ、ビルドやデバッグ実行用の設定ファイルが自動的に作成されます。

この時点でShift+Ctrl+B(MacではShift+Cmd+B)を押すとビルドが実行されるのでエラーが無いことを確認しておきます。




ステップ2 - 依存パッケージを追加する


dotnet add package Microsoft.EntityFrameworkCore.SqlServer

上のコマンドを実行すると「MySampleWeb.csproj」ファイルにEntityFrameworkでSqlServerに接続するためのパッケージ参照のエントリが追加されます。



ステップ3 - モデルクラスを作成する


プロジェクト直下にDataというフォルダを作って、そこにCustomer.csファイルを作成します。





ステップ4 - DbContextクラスを作成する




コンストラクタのパラメータでoptionsを受け取るようになっている点に注意して下さい。これを忘れるとデータベースに接続出来ずエラーになります。




ステップ5 - リポジトリクラスを作成する




とりあえずGetAll()とFind()のみ実装しておきます。

CustomerRepositoryクラスのコンストラクタでNorthWindContextのインスタンスを受け取れるようになっている点に注目です。

ASP.NET CoreではDbContextなどのインスタンスはこの様にDependency Injection(DI)で受け取るというのが原則です。





ステップ6 - 設定ファイルにDB接続文字列を追加する




SQLサーバーの指定、ユーザーID、パスワードの指定は適宜変更して下さい。




ステップ7 - StartupクラスにDIの設定を追加する




AddDbContext()

このメソッドでDbContextのDIを設定しています。


AddScoped()

このメソッドでリポジトリクラスのDIを設定しています。「ICustomerRepositoryのインスタンスがどこかで要求されたら、CustomerRepositoryのインスタンスを生成して注入してね」という意味になります。

AddSingleton()やAddTransient()などもありますが、それぞれ注入されるインスタンスが維持される期間が異なります。

Dependency Injection in ASP.NET Core | Microsoft Docs
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection


AddScoped()の場合はひとつのHTTPリクエストについてひとつのインスタンスが生成されます。リポジトリクラスの中で使っているEntityFrameworkはスレッドセーフではないので AddSingleton() はここでは使えません。





ステップ8 - Controllerを作成する


ControllersフォルダにCustomersController.csファイルを新規作成します。



コンストラクタでリポジトリクラスのインスタンスを受け取るようになっています。ここでステップ7で設定したDIが効いてきます。

通常のWebアプリケーションとして動いている場合は、このDIのおかげでASP.NET Coreが自動的にCustomerRepositoryのインスタンスを生成してコントローラに渡してくれます。

でも単体テストでコントローラの動作をテストしたい場合などでは、自前でモックのインスタンスを生成してコントローラに渡すことが出来ます。DIを使うことでクラス同士が疎結合になっているわけですね。

密結合と疎結合の概念やDIについては下のページの説明がとても分かりやすいと思います。

ASP.NET - 依存関係の挿入による ASP.NET Core でのクリーンなコードの作成


これでカスタマーの情報を取得するWeb APIが出来ました。

VS Code上でF5またはCtrl+F5(MacではCmd+F5)を押して実行して見てください。ブラウザが開いてデフォルトのHomeページが表示されるので、下のURLを手入力します。

先頭から3件取得
http://localhost:5000/api/customers?offset=0&limit=3

カスタマーIDを指定して取得
http://localhost:5000/api/customers/ANATR



データベースから取得した情報がJSON形式で表示されれば成功です!


これからは.NETでのWeb開発といえば「ASP.NET Core」という事になって行くと思います。

WindowsでもMacでもLinuxでも全く同じように開発が出来るのがいい感じです。


今回のソースコードはこちらにあります。

https://github.com/mikehibm/AspNetCore-MySampleWeb



参考URL:
ASP.NET Core MVC with Entity Framework Core - Tutorial 1 of 10
チュートリアル: ASP.NET Core MVC で Web API を作成する | Microsoft Docs 






 

2017年3月18日

REST APIに代わる効率的なバックエンドサーバーとの通信方法とは

最近ReactやAngularでREST APIを呼んで動くアプリケーションをいくつか作っています。

ただ、特定の画面を表示するためのデータを得るために何回にも分けてAPIを呼び出す必要があるような場面が結構あり、なんとなくモヤモヤしたものを感じていました。

調べてみると2015年ぐらいからNetflixやFacebookといった企業からREST APIに代わるモノが出てきているようです。





Falcor


Falcorで実現する効率的なfetch - Falcorとは | CodeGrid

Falcor入門 1日目 Falcorとは何者か - Qiita

これらを読んだかぎりでは Falcor 良さそうな気がしますが、GitHubを見ると最近はあまり活発に更新されていない(?)ような感じもします。どうなんでしょうね。


GraphQL


GitHub APIから学ぶ次世代のAPI実装方式GraphQL - Qiita

GraphQL入門 - 使いたくなるGraphQL - Qiita

Apolloを使って、React-Reduxの世界にGraphQLを持ち込む



GraphQLについては前から聞いたことはありましたが、何やらややこしそうなので近づかないようにしていました。

ただ今回下の動画を観てGitHubのAPIが昨年からGraphQLに対応していることを知り、これはと思って調べてみました。これからもう少し勉強してみようかと思います。

Phil Haack - GitHub | On .NET | Channel 9 


今年は GraphQL の人気が上がって来そうな気がなんとなくしています。





2017年3月8日

リバースプロキシを使っているWebサイトでHTTPからHTTPSに自動的にリダイレクトさせるための設定

IIS 8.5 での設定方法です。

まず、Webサーバーに「URL Rewrite」モジュールをインストールします。

URL Rewrite : The Official Microsoft IIS Site
https://www.iis.net/downloads/microsoft/url-rewrite


次に、該当のサイト直下のWeb.configを編集してsystem.webServerセクションにrewriteの設定を追加します。

リバースプロキシ(例えばAzureのApplication Gatewayなど)を使っていない場合は、こちらのサイトにある方法で問題無いと思います。

WebサイトでHTTPSへリダイレクトさせる | たんたか
http://blogs.gine2.jp/taka/archives/2790

リバースプロキシを使っている場合は、この方法だとリダイレクトが無限ループになってしまいます。

そこで下のように書き換えます。




これで無事思った通りにHTTPからHTTPSにリダイレクトしてくれるようになります。


リバースプロキシから送られてくるX_FORWARDED_PROTOヘッダの値をチェックして、「https」でない場合だけリダイレクトするという条件になっています。


また{REQUEST_URI}を使った場合は「appendQueryString="false"」を付けておかないと、REQUEST_URI自体が既にクエリー文字列を含んでいるためにURLの「?」以降の部分が2回重複して追加されてしまうようです。

URL Rewriteモジュールを使うとプログラムを書き換えずに対応出来るので便利ですね!






2017年1月25日

MSBuildでVisual Studioのプロジェクトをビルドした時に参照しているDLLが出力フォルダにコピーされない問題の対処法

表題の通りの問題にぶつかって、今日は解決策を見つけるまでに数時間もかかってしまいました。せっかくなのでメモしておきます。


事の発端は、あるASP.NET MVCのプロジェクトでActiveReportsのバージョンを更新したことでした。ライブラリの参照やソースコードを自動で更新してくれるツールがあるのでそれを使ってプロジェクトを更新しました。

するとその直後から、MSBuild.exeを使ってコマンドラインからビルドした場合にアウトプット先のフォルダにActiveReportsのDLLファイルがコピーされないという現象が発生しだしました。

Visual Studio の中でビルドを行った場合には全く問題ありません。


色々調べましたが結局、該当のプロジェクトファイル(.csproj)をエディタで開いて以下のように直接書き換えることで解決しました。


変更前



変更後

<Reference>タグの中に<Private>True</Private>という記述を追加すればOKです。

この設定は Visual StudioのSolution Explorer の表示上は「Copy Local」というプロパティに当たる部分になります。

問題は、これが初期状態だと「True」と表示されているのに、実際にはプロジェクトファイルでは上の画像の変更前の状態にあるとおり、<Private>True</Private>という記述が無いということです。このせいでMSBuild.exeが正しく動作しなかったという事みたいです。

プロジェクトファイルを直接書き換える他にも、Visual Studio上で「Copy Local」を一旦Falseにして保存して、Trueに戻してからもう一度プロジェクトを保存する、という手順でも同様の効果がある様です。



参考URL:
visual studio - MSBuild doesn't copy references (DLL files) if using project dependencies in solution - Stack Overflow






 

2017年1月24日

今さらながら Toshiba dynaPad を買ってみた

年末にChromebook FlipをeBayで買ったところ不良品にあたって失敗したので、どうしようかな~と考えていました。

結局、1年以上前に発売された機種ですが 「Toshiba dynaPad」を買うことにしました。

Microsoft Storeでこんな感じで$449でセールされていました。


今調べたら発売当初の定価が$569らしいので、落ち着いて考えると1年落ちのモデルでこの価格というのは本当にお買い得なのかどうかちょっと微妙な感じもします。

でも12インチサイズで560gという驚きの軽さと、ワコムと共同開発したという2048段階筆圧感知の「TruePen」に惹かれました。


今のところ考えている用途は、次の3つです。


  1. 家族がリビングでさっとWebを見たり動画を見たりする。
  2. 子供の宿題やお絵かき用
  3. 紙のノートを置き換えることが出来るか、僕の実験用。



デザインが良いのでリビングに置いておくのに良いかも。

縦置きでのWeb閲覧も快適。

2週間ほど使っていますが、今のところ良い感じです。特に6.9mmという薄さとこの軽さは最高です。

Webサイトや動画の閲覧には、同時にたくさんのタブを開かないようにさえ気をつければ全く問題ありません。

子供に使わせるとすぐに独占されてしまいそうなので、まだ使わせていません。(笑)

仕事のミーティングなどで紙のノートの替わりに使えるのか、という点についてはかなり実用的に使えそうです。付属のペンの書き味は僕がMicrosoft StoreやApple Storeの店頭でSurfaceやiPad Proを触った感触と比べてもまったく遜色ありません。というよりもこちらの方が若干反応が良い気がします。細かい文字を素早く書いた時でもきっちり追随してくれます。ただ画面がつるつると滑るのでそこだけは紙の感触とはだいぶ違って慣れが必要だと思います。

CPUがAtom x5-Z8300 なのでところどころで一瞬待たされる感じはあります。これは価格からすると仕方ないのかなとは思いますが、今後i5やi7バージョンが出たらぜひ仕事用にも買いたいと思わせられる機種です。






 .