見出し画像

axios.deleteでデータ送信する方法

こんにちは。昨年10月にSHIFTに入社した三輪です。SHIFT社内のプロダクト開発に従事しております。最近は発足したばかりの基盤開発チームにスクラムの体制を取り入れようとしております。

基盤開発チームではアーキテクチャとしてマイクロサービスを採用しており、各サービスのフロントエンドはVue.js、バックエンドはExpressで開発を進めています。

Vue側からのAPI呼び出しではaxiosを使っておりますが、最近delete時にデータ送信する場合の実装ってどうやるんだっけ?と少しハマったことがあったので記事にすることにしました。


axiosとは

axiosのドキュメントの見出しではこう定義されています。

Promise based HTTP client for the browser and node.js

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環境どちらでも使うことの出来るHTTPクライアントであると言っています。
事実その通りで、非常に使いやすくシンプルな構文で、かつ柔軟にHTTP通信のコードが書けるのが特徴です。

POST, PUT, PATCHの場合

axios.post,axios.put,axios.patchの場合は第一引数にURL、第二引数にpayload、第三引数(option)にheaderなどの情報を入れてあげればOKです。

import axios from 'axios';

try {
  const url = 'https://example.com/blog'
  const payload = {
    title: 'テスト',
    body: 'テスト'
  }
  const headers = {
    'Content-Type': 'application/json'
  }
  // put,patchの場合も基本的にはこの書き方
  axios.post(url, payload, { headers: headers })
} catch(e) {
  console.error(e)
}

axiosのGithubのexamplesにも載っていますね。
https://github.com/axios/axios/blob/master/examples/post/index.html#L27

DELETEの場合

axios.deleteでも、postと同じように第二引数にデータを与えてあげればいいのかなと思いましたが、違いました。
これだと正常にAPIコールできません。
今回の例ではバックエンドにExpressを使っていますが、「415 Unsupported Media Type」と怒られてしまいます。(これはExpressデフォルトのエラー)
(※ちなみに表示されているIPは私の開発用仮想環境のIPです。外部からのアクセスは出来ないようになっているので予めご了承ください)

import axios from 'axios';

try {
  const url = 'https://example.com/blog'
  const payload = {
    deleted_at: '2022-01-05'
  }
  axios.delete(url, payload) // APIコールできない
} catch(e) {
  console.error(e)
}

正解は、deleteは第二引数にオプションのオブジェクトを受け取るので、この中でdataプロパティを定義してそこにデータを渡してあげます。
ここでのレスポンスは実装されているサービスによって変わりますが、弊社のサービスでは204を返却しています。

import axios from 'axios';

try {
  const url = 'https://example.com/blog'
  const payload = {
    deleted_at: '2022-01-05'
  }
  axios.delete(url, {
    data: payload
  }) // 正常にAPIコールできる
} catch(e) {
  console.error(e)
}

これでaxios.deleteでデータを送信出来るようになりました。

実際のコードを読んでみる

エンジニアたるもの、ライブラリの調査時は中身のコードを読むべし!
ということで、axiosの実際のコードを読んでみましょう!
axiosのhttpメソッドはここから下で定義されています。
https://github.com/axios/axios/blob/master/lib/core/Axios.js#L133

// 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
    }));
  };
});

Axios.prototype[method] = function(url, config)の部分で、代入されている関数の引数がpostやdeleteなどのメソッドの引数となります。
postやput,patchでは関数の第二引数にdataが定義されているのに対し、getやdeleteでは同様の定義がされておらず、dataを定義する場合はconfigというものの中のdataプロパティとして定義する必要があることがわかります。
で、このconfigというのが、postであれば第三引数として、deleteであれば第二引数としてオプションとしてオブジェクトで渡すものになります。
そしてどのhttpメソッドも、最終的にはrequestメソッドという1つのメソッドから実行されているようですね。

まとめ

普段使っているaxiosの中のコードを呼んだのは今回が初めてだったので勉強になりました。
Rubyライブラリの中身はがっつりメタプログラミングされていて読むのがしんどいですが、NodeライブラリはRubyライブラリと違ってライブラリの中身のコードが読みやすくていいですね。

_________________________________

執筆者プロフィール:Taiga Miwa
受託会社で2年ほど勤務し、Railsを使ったWebアプリの新規開発を主に担当。 Rails, React, Vue, GraphQLなどモダンな技術を使って開発を行っていた。 最近SHIFTにジョインし、アーキテクト目指して修行中。得意技はRubyと魚捌き。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/