見出し画像

application/jsonとapplication/x-www-form-urlencodedの違いを調べてみた

こんにちは。最近SHIFTに入社した三輪です。SHIFT社内のプロダクト開発に従事しております。
今までAPI呼び出しではContent-typeは何気なくappliation/jsonで指定していましたが、application/x-www-form-urlencodedでないとダメ!と怒られる場面に遭遇したので、この2つの違いについて調べてみました。
しかし、そもそもContent-typeとは何なのか、メディアタイプとよく似ているが違うものなのか、理解していなかったのでそこから調べることにしました。


メディアタイプとは

画像、音声、動画、テキストなど、ファイル種類を表すための情報のことです。MIMEタイプとも呼ばれています
具体的にどんなものがあるかというと…

テキスト型 ・テキスト: text/plain ・HTML: text/html ・javascript: text/ javascript

画像型 ・GIF: image/gif ・JPEG: image/jpeg ・PNG: image/png

文書型 ・JSON: application/json ・PDF: application/pdf ・Word: application/msword

などなど、一覧はこちらで見れます。

見てわかる通り、A/Bという形式で表現されており、Aのことをタイプ、Bのことをサブタイプと呼びます。
タイプではそのデータ型が当てはまる大枠のカテゴリを表し、サブタイプではより正確なデータ型を表します。

余談ですがWindowsとMacOSとでCSVファイルのメディアタイプが違っており、もっと言うと、同じWindowsでもExcelがあるかないかでメディアタイプが異なります。
MacOS: text/csv
Windows(Excelあり): application/vnd.ms-excel
Windows(Excelなし): application/octet-stream

なので、ファイルアップロード機能でCSVファイルだけを許可する場合、メディアタイプではなく拡張子でバリデーションする必要があります。
初めてフロントエンドでCSVアップロード機能を実装した時は見事にこれにはまりました…
こんなん知らんとわかんねえよ…

Content-typeとは

HTTP通信において、ファイル種類を表すための情報を設定するためのヘッダー項目のこと。ここで指定する内容はメディアタイプを指定することが多いですが、文字エンコードであるcharsetや、データ境界値であるboundaryも必要に応じて指定もすることが出来ます。
ex. application/json; charset=UTF-8

メディアタイプと何が違うの?となってしまいますが、メディアタイプが情報そのものであるのに対し、Content-typeはHTTP通信のヘッダーにおいて、送信する情報がどのデータ型かを設定する項目名です。

Content-type = メディアタイプ + 文字コード + データ境界値

と理解しておけば問題ないでしょう。

application/jsonとapplication/x-www-form-urlencodedの違い

さて、本題に入っていきましょう。この2つはタイプが同じで、サブタイプが異なることになります。


application/json

jsonフォーマットのことで、エンジニアならよく知っている形式ですね。
{ "title": "test", "number": 1 }みたいな形になるやつです。

具体例(VSCodeのRestClient使ってます)

# リクエスト
POST https://postman-echo.com/post
Content-Type: application/json

{
  "title": "test",
  "number": 1
}


# レスポンス
HTTP/1.1 200 OK
Date: Wed, 01 Dec 2021 01:11:09 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 415
Connection: close
ETag: W/"19f-iSoVzdO7x9iG7W7qPnV8qOH+yIU"
Vary: Accept-Encoding
set-cookie: sails.sid=s%3AG-Mn1-jcp1mzHAsetCx3i191RllORw2K.dlAqTsh4Q6wiKpK%2Fv2kAQmLUSbf0Jatql2M5TQUEPoo; Path=/; HttpOnly

{
  "args": {},
  "data": {
    "title": "test",
    "number": 1
  },
  "files": {},
  "form": {},
  "headers": {
    "x-forwarded-proto": "https",
    "x-forwarded-port": "443",
    "host": "postman-echo.com",
    "x-amzn-trace-id": "Root=1-61a6cbad-19be676d0e9c48901e926f42",
    "content-length": "34",
    "user-agent": "vscode-restclient",
    "content-type": "application/json",
    "accept-encoding": "gzip, deflate"
  },
  "json": {
    "title": "test",
    "number": 1
  },
  "url": "https://postman-echo.com/post"
}

※ noteのEditorでは「set-cookie」がエラーとなり記事が保存できない(原因不明)ため、ハイフンを全角にしております。

application/x-www-form-urlencoded

エンコードされたURLのデータフォーマットのことです

application/x-www-form-urlencoded

エンコードされたURLのデータフォーマットのことです。
例えば title=test&number=1 をエンコードしたら、title%3Dtest%26number%3D1となります。

具体例

# リクエスト
POST https://postman-echo.com/post
Content-Type: application/x-www-form-urlencoded

title%3Dtest%26number%3D1


# レスポンス
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "title=test&number=1": ""
  },
  "headers": {
    "x-forwarded-proto": "https",
    "x-forwarded-port": "443",
    "host": "postman-echo.com",
    "x-amzn-trace-id": "Root=1-61a6cc1f-7bb7940b24fb76d86a09c9d3",
    "content-length": "25",
    "user-agent": "vscode-restclient",
    "content-type": "application/x-www-form-urlencoded",
    "accept-encoding": "gzip, deflate",
    "cookie": "sails.sid=s%3AG-Mn1-jcp1mzHAsetCx3i191RllORw2K.dlAqTsh4Q6wiKpK%2Fv2kAQmLUSbf0Jatql2M5TQUEPoo"
  },
  "json": {
    "title=test&number=1": ""
  },
  "url": "https://postman-echo.com/post"
}

application/jsonもしくはapplication/x-www-form-urlencodedをHTTPヘッダーに指定することで、どういうデータをPOSTしているかをサーバ側に知らせています。

application/jsonもしくはapplication/x-www-form-urlencodedをHTTPヘッダーに指定することで、どういうデータをPOSTしているかをサーバ側に知らせています。

まとめ

Content-typeとはどういうものかを理解するところから進めると、すんなり理解できる内容だったと思います。
今までほとんどJSONかまれにXMLしか使ってきませんでしたが、application/x-www-form-urlencodedが出てきたことで初めてContent-type、メディアタイプを理解するきっかけになりました。

__________________________________

執筆者プロフィール: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/