0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Axiosのdeleteでデータを送りたい

Last updated at Posted at 2022-01-31

今回、React側とAWS lambda上のそれぞれでAxiosのdeleteでデータを送る必要があったのですが、たまたま実装の仕方が違ったことが原因で分かったこととしったことを忘れないようにするために記事にしました。

そもそもAxiosってなに?

※以下Axiosの公式ドキュメントの見出しより
Axios is a simple promise based HTTP client for the browser and node.js. 
Axios provides a simple to use library in a small package with a very extensible interface.

Axiosは、ブラウザーとnode.js用のシンプルなPromiseベースのHTTPクライアントです。
Axiosは、非常に拡張可能なインターフェイスを備えた小さなパッケージで、使いやすいライブラリを提供します。

ドキュメントに書いてある通りですが、シンプルにHTTPリクエストを実行できる便利なライブラリになります。
sample

import axios from "axios";
axios.get('/path')
  .then((res) => {
    console.log(res.data)
  });

このように非常に短い内容で済みXMLHttpRequestのように長々と記述する必要のない便利なライブラリです。

何が起きたか

冒頭にも記載しましたがフロントでもともと呼び出す予定のAPIがIP制限の関係でlambda上で呼び出す必要が発生しました。
その際にリクエストの仕方が違ったためlambda側でうまくコールができないといった事象が起きました。

フロント側は一つのファイルにaxiosを呼び出すため処理が書いてありその関数をimportしてほかの箇所で使いまわすつくりになっていました。
axiosの関数(getなど)は使わずに第2引数のmethodにGETやPOSTを渡して使うのでdeleteの時も第3引数のbodyにあたる内容も送れていました。

import axios from "axios";
export const invokeApi = (path, method, data,  options?) => {
  const headers = {
    'Content-Type': 'application/json'
  };
  return axios({
    url: `url/${path}`,
    method,
    data,
    headers: extend(headers, options)
  });
};

使いたい箇所

import { invokeApi } from '/file';
invokeApi('path', 'DELETE', { ids: [1,2,3] });

lambda側では使いまわすといったことはないため、フロント側とは違ってAxiosの関数であるdeleteをドキュメントなど一切読まずにpostと同じように呼び出しました。
有識者の方はこの時点でお気づきだと思いますが、リクエストを送っているAPI側からはerror ids requiredといったエラーが返ってきていました。

const axios = require('axios');
exports.handler  = async(event, context, callback) => {
  const { headers, body, pathParameters, queryStringParameters } = event;
  const headers = {
    'Content-Type': 'application/json'
  }
  const res = await axios.delete(
    'url',
    body,
    { headers }
  );
}

原因

根っこの原因はAxiosのHTTPリクエストメソッドごとに実装が分かれているのが原因となります。
Axios githubより抜粋

// Provide aliases for supported request methods
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
  /*eslint func-names:0*/
  Axios.prototype[method] = function(url, config) {
    return this.request(mergeConfig(config || {}, {
      method: method,
      url: url,
      data: (config || {}).data
    }));
  };
});

utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
  /*eslint func-names:0*/
  Axios.prototype[method] = function(url, data, config) {
    return this.request(mergeConfig(config || {}, {
      method: method,
      url: url,
      data: data
    }));
  };
});

このようにGET, DELETEとPOST, PUT, PATCHで実装が異なっています。
おそらくですが、GET、DELETEは仕様上bodyをつけることは禁止されていないのですが、POST, PUTはcontent-lengthを付けることが必須なのに対して
GET, DELETEは任意で必須ではないためこのようになっているだと思われます。

なのでlambdda側の関数をこのように修正したところAPIからエラーが返ってくることがなく無事に動きました。

  const res = await axios.delete(
    'url',
-   body 
-   { headers }
+   {
+     headers,
+     data:body
+   }
  );

まとめ

たまたま発生した事態でいろいろと調べてHTTP リクエストを雰囲気で使っていることを痛感しました
そもそもbodyを用意するためにはcontent-lengthが必要なこともふんわりPOSTとPUTの時はあることは気が付いていましたが、GETとDELETEにはないのは今まで気が付いていなかったのでしっかり理解して使っていかないと大変なことになりそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?