こんにちは、フロントエンドエンジニアの小張(@kobari41257)です。
今回は特定環境で一部機能が動作しない事象の対応として、PATCHメソッドを使ったAPIをPOSTメソッドに置き換え、新規実装ではPATCHメソッドを使わないという意思決定を行ったことについてご紹介します。
目次
「メディアリストが保存できない」というお問い合わせ
先日「メディアリストを保存しようとするとエラーが発生する」というお問い合わせを複数件いただきました。
メディアリスト機能について
メディアリストとは、プレスリリースを届けたいメディアを選び、一覧化した配信先リストのことです。
このリストを活用することで、自社の発信内容に最も合った媒体へプレスリリースを発信することができます。
詳しくはこちらをご覧ください。
https://tayori.com/q/prtimes-faq/detail/245110/


メディアリストの保存はREST APIで行っており、そのAPIのエラー情報はNew RelicのnoticeError関数によって記録されていました。
そこでNew Relicに記録されている情報を調べたところ、メディアリスト保存APIから501エラーが返っていることが確認できました。
501エラーが返されている箇所の調査
501エラーを返している箇所を特定するため、APIがホストされているprtimes.jp へのリクエストが最初に到達する箇所であるFastlyのアクセスログを調査しました。
しかし、該当のAPIが501エラーを返しているログは1件も見つからなかったため、PR TIMESシステムに到達する前に501エラーが返されていることがわかりました。
アクセスログを始めとするFastlyの設定については、こちらの記事をご覧ください。


こんにちは、インフラチームテックリードの櫻井です。 今回はプレスリリース配信サービスの prtimes.jp で使用しているCDNをCloudFrontからFastlyに移行したことについ…
なお該当のAPI以外へのリクエストは正常に処理できていたため、PR TIMESへのリクエストが一律でブロックされている状況ではなかったと考えられます。
根本原因の仮説と検証
ここまでの調査でわかったことは以下です。
- 該当のお客様から行われたメディアリスト保存APIへのAJAXリクエストは、501エラーとしてNew Relicに記録されている。
- 該当のお客様から行われたメディアリスト保存APIへのAJAXリクエストは、PR TIMESシステムに到達していない。
- 該当のお客様から行われた他のAPIへのリクエストは、正常にレスポンスを返せている。
上記の事実を踏まえ、調査チームでは以下のような仮説を立てました。
- お客様環境ではセキュリティソフトの設定などにより、メディアリスト保存APIのみがブロックされ、501エラーが返されているのではないか。
仮にメディアリスト保存APIがセキュリティソフトなどで機械的にブロックされているとした場合、リクエストから判別できる何かしらの情報が関係していると考えました。
実際にメディアリスト保存APIが他のAPIと異なっていた点として、リクエストメソッドにPATCHを使っていたことがありました。
そこで上記の仮説からさらに踏み込んで、以下のような仮説を立てました。
- メディアリスト保存APIのみがブロックされる原因として、リクエストメソッドがPATCHであることが関係しているのではないか。
そこでお問い合わせいただいたお客様にご協力いただき、PATCH APIを使っている他の機能が使えるか確認していただきました。


その結果、同じくPATCH APIが使われている他の機能も使用できないことがわかりました。
そのため「PATCHメソッドがセキュリティソフトの設定などによりブロックされている」ことが原因と結論づけました。
PATCHメソッドが動作しない事象に対する対応
暫定対応
お問い合わせをいただいたお客様に対しては個別に対応し、直近のお困りごとの解決を図りました。
恒久対応
原因の調査を踏まえOpenAPI Schemaを調べたところ、3つのAPIでPATCHメソッドが使われていることがわかりました。
これらのAPIをPOSTメソッドに変更する対応を行い、お問い合わせから2日後に事象の解消に至りました。
その他の対応
上記の対応で既存のAPIは問題なく動作するようになりましたが、今後新しいPATCH APIが実装されないようにOpenAPI Schemaに対するLintルールを追加しました。
すでにspectralというLinterを導入していたため、新たなルールを自作する形で対応しました。
spectralについて
Stoplightによって開発されているYAMLやJSON向けのLinterです。
OpenAPI向けのルールセットが提供されており、OpenAPI SchemaへのLinterとして使用できます。
Lintルールを自作することで、細かなカスタマイズが可能です。
https://github.com/stoplightio/spectral
# .spectral.yaml
rules:
allowed-methods-only:
severity: error
given: "$.paths.*"
then:
field: "@key"
function: pattern
functionOptions:
# GET、POST、DELETE以外は禁止する
notMatch: "^(put|patch|head|options|trace)$"
overrides:
# 既存のPUTメソッドがエラーにならないようにする
- files:
- "path/to/既存のPUTメソッド"
rules:
allowed-methods-only: "off"
今回問題がなかったPUTメソッドについても、新規実装ではより一般的なPOSTメソッドを使用する方針になったため合わせて禁止するようにしました。
既存のPUT APIに関してはoverrides でignoreするようにしています。
まとめ
RFC9110においてPUTは「冪等性がある」リソースの置き換えに用いるとされ、RFC5789においてPATCHは「部分的なリソースの更新」に用いるとされています。
APIの性質に応じてHTTPメソッドを使い分けている方もいるかと思いますが、今回の事象を受けてPR TIMESではPOSTに統一するという意思決定を行いました。
皆さんの開発でHTTPメソッドの選択をする際の一つの参考になれば嬉しいです。
PR TIMESを利用されるお客様の環境は、導入しているセキュリティソフトの違いも含めてさまざまです。
PR TIMESのユーザー数が増えるにしたがって、今回のような特定環境で動かないという事象も増えてくると思われます。
すべての環境に対応することは難しいですが、様々な環境でも使っていただけるように対応を続けたいと思います。
We are hiring!
フロントエンドエンジニアを含む各種ポジションでの採用を進めています!興味があればぜひご応募ください。
株式会社PR TIMESでは現在03-4. 開発部 フロントエンドエンジニアを募集しています。
元の記事を確認する