🐥

zodの z.url() / z.httpUrl() の違い

に公開

はじめに

Web URLのバリデーションチェックをする際、JavaScriptのバリデーションライブラリZodのurlに関するメソッドがあるのですがz.url()z.httpUrl()は同じように見えて実は異なるメソッドみたいなので今回その違いをまとめたいと思います。

割愛

  • Zodを使用するまでのランタイム環境構築について
  • Zodの使い方について

z.url()

最初はこのメソッドをつかえばurl全般のバリデーションチェックは大丈夫だろうと思っていました。
ただ実はバリデーションチェックの受け皿はかなり大きめで、メソッドの中身はnew URL()であり、バリデーションチェック結果が想定外になりかねないということがわかりました。
Zodの公式でもある通り以下の場合バリデーションチェックを通過します。

  • urlの型になっていれば問題なし ※https://example.comなど
  • .com, .jpなどurlの末尾がない
  • http / https のどちらか
  • mail関連などhttp以外のプロトコル

テストなどでバリデートされていないことは気づけるとは思いますがメソッドの名前だけで判断すると気づくタイミングが遅れる気がします。(ちゃんと調べてから使えよなんですが。。。)
このメソッドでバリデーションチェックを設けるにはZodの公式でもある通りメソッドの引数を正しく設定することが必要です。

example.js
    z.url({
      protocol: /^https?$/, // httpsのみ許容
      hostname: z.regexes.domain // Zod側でWEB URLの正規表現は設定済み
    });

z.httpUrl()

肝心なz.url()との違いですが
Githubのリポジトリを確認したところ、上記で示したurlのバリデーションチェックをパッケージ化したもののようです。
使用用途としてz.url()でWEB URLをバリデーションチェックすること多かったことと毎度プロトコルとホストを指定するのはユーザーとしては面倒なのでパッケージ化してしまおうという意図ではないかと思います。
https://github.com/colinhacks/zod

まとめ

Zodのz.url(), z.httpUrl()の違いをまとめました。2つの使い分けとしては下記です。

z.url() z.httpUrl()
mailプロトコルなど多様なスキームを許容 WEB URLのみを許容

ただ調査した結果、分かったことですが
URLのバリデーションチェックもちろんしてくれますが、そのURLが生きているかどうかまではわからないということです。(バリデーションチェック後にurlにリクエストして200番台などの適切なレスポンスが返却されるかどうかということ)
それを実装するには先ほどのメソッドにチェーンしてRefine, superRefineなど組み合わせてカスタムメソッドを構築する必要がありそうです。

参考

https://zod.dev/api#urls
https://developer.mozilla.org/ja/docs/Web/API/URL/URL

Discussion