REST API
spring bootでREST APIを作ってみたので、それをjavascriptのfetch apiを使って取得してみる
GET
今回はGETだけ。 パラメータをつけて送ったらそのまま結果を返すだけのAPI
http://localhost:8080/Hello/get?name=name&message=message {"name":"name","message":"message"}
こんな感じで取得してみた
const getFunc = (url, param) => { // パラメータ作成 param = new URLSearchParams(param); return fetch(`${url}?` + param) .then(res => { // リクエスト成功、もしくは400ならjsonを返す if (res.ok || res.status === 400) { return res.json(); } // 成功しなかった場合はエラーを投げる throw Error(); }) .catch(error => "エラーが発生しました"); }; // バリデーションエラーの内容を返す const validError = (errorData) => { const errorResult = errorData.errors.map(data => { return { field: data.field, message: data.defaultMessage, }; }); return { error: errorResult }; }; // fetchはpromiseを返すので、awaitで処理待ちして値を取得 const helloFunc = async () => { const param = { name: "name", message: "message" }; const httpGetUrl = "http://localhost:8080/Hello/get"; const getResult = await getFunc(httpGetUrl, param); console.log("get", !getResult.status ? getResult : validError(getResult).error); };
URLSearchParams
URLSearchParams知らなかったけど便利。
オブジェクトを用意しておけば、?name=ほにゃららみたいな文字列に変換してくれます。
GETでパラメータを送るときは、これを使えばOK。
今日まで知らなかった…。
getFunc
今回のメインの処理。
fetchはリクエストを投げて、promiseを返します。
サーバがネットワークエラーの場合、TypeErrorでcatchに渡るみたいですが、サーバに通った後のバリデーションエラー等の場合は、catchに渡りません。
ってことで、正常な結果が返っているか判断して、異常な場合はerrorを投げています。異常は全部catchする感じ。
正常はresponse.okで判断をするのですが、今回はバリデーションエラーの場合はエラーに渡したくなかったので、400は正常処理にしました。
.json()は結果をjson形式で返します。これもPromise。
validError
バリデーションエラーが発生した場合の結果を見てましたが、errorsにメッセージや発生したフィールドが入っていました。
errorsは配列で保持ししていたので、mapでfieldとmessageだけ抜き出す関数を作っています。
helloFunc
メインの処理。fetchのpromiseをthenで繋げるのではなく、async/awaitで処理しています。
前の実装でthenで繋げまくったら大変なことになったので…。
ってことでURLとParamを作り、awaitでGETリクエストを投げる。
処理を待って、コンソールに出力しています。
正常な場合はstatusは持ちませんが、異常な場合はhttpのエラーコードを持っています。
なので、statusがある場合はvalidErrorでエラー情報を取得しました。
正常
get {name: 'name', message: 'message'}
異常(nameがnullだと異常)
get [{…}] 0: {field: 'name', message: '空要素は許可されていません'}
異常(ネットワークエラー)
get エラーが発生しました
おわり
とりあえず、今回はバリデーションエラーだけ考えてつくったけど、実際はもっとエラー処理を丁寧にしなきゃですね。
明日はpostについて書こうと思います。