ケバブケース変換は「Java の名前を“URL やフロントエンドの世界”に合わせる」技
ここまで出てきたキャメルケース(userName)、スネークケース(user_name)に続いて、
フロントエンドや URL でよく使われるのが ケバブケース(kebab-case) です。
user-nameuser-profile-imagecreated-at
といった、「単語をハイフン - でつなぐ」スタイルですね。
REST API のパス、フロントエンドのコンポーネント名、CSS のクラス名などでよく見かけます。
Java の世界ではキャメルケースが主流なので、
「userName → user-name」のように変換できるユーティリティを持っておくと、
バックエンドとフロントエンド、Java と URL の橋渡しがとても楽になります。
ケバブケースの基本イメージと使いどころ
kebab-case と lower-kebab-case
ケバブケースは、単語をハイフンでつなぐ書き方です。
一般的には、すべて小文字で書く lower-kebab-case がよく使われます。
user-nameuser-profilemax-retry-count
URL パスや JSON のキー、CSS クラス名などで「読みやすくて、目に優しい」命名として好まれます。
今回のユーティリティでは、
- camelCase / PascalCase → kebab-case(小文字)
を軸にして実装していきます。
基本方針:「スネークケースと同じ発想で、区切り文字だけ変える」
「大文字の境目に区切りを入れる」という考え方は同じ
キャメルケース → スネークケース変換では、
「小文字+大文字の境目に _ を挟む」という発想でした。
ケバブケースも本質は同じで、
「小文字+大文字の境目に - を挟む」だけです。
userName → user-Name → 小文字化 → user-namecreatedAt → created-At → 小文字化 → created-at
つまり、スネークケース変換のロジックをほぼそのまま流用しつつ、
「アンダースコア _ をハイフン - に変える」だけで実現できます。
実装:キャメルケースを kebab-case に変換する
正規表現で「小文字と大文字の境目」にハイフンを挟む
まずは、userName → user-name のような基本変換を実装します。
import java.util.Locale;
public final class KebabCases {
private KebabCases() {}
public static String toKebab(String text) {
if (text == null || text.isEmpty()) {
return text;
}
// 1. "userName" → "user-Name" のように、境目にハイフンを挟む
String withHyphen = text.replaceAll("([a-z0-9])([A-Z])", "$1-$2");
// 2. 全体を小文字にする
return withHyphen.toLowerCase(Locale.ROOT);
}
}
Java使い方はこうなります。
System.out.println(KebabCases.toKebab("userName")); // user-name
System.out.println(KebabCases.toKebab("UserName")); // user-name
System.out.println(KebabCases.toKebab("createdAt")); // created-at
System.out.println(KebabCases.toKebab("userID")); // user-id
System.out.println(KebabCases.toKebab("URLValue")); // url-value
Javaここで深掘りしたい重要ポイントは二つです。
一つ目は、「([a-z0-9])([A-Z]) という正規表現で、“小文字または数字の直後に大文字が来る場所”を見つけている」ことです。userName なら rN のところでマッチし、$1-$2 によって r-Name になります。createdAt なら dA のところで d-At になります。
二つ目は、「ハイフンを挟んだあとで、全体を小文字にしている」ことです。UserName のように先頭が大文字でも、User-Name → user-name となり、URLValue のような略語も URL-Value → url-value という形に落ち着きます。
この「境目に - を挟んでから、小文字に落とす」という二段構えを覚えておくと、
キャメルケース → ケバブケース変換のロジックがとてもシンプルに見えてきます。
例題:Java のフィールド名から URL パス用のセグメント名を作る
userName → /user-name のような変換
REST API の設計で、URL パスをケバブケースで書きたいことがあります。
/user-name/user-profile/max-retry-count
このとき、「Java のメソッド名やフィールド名から URL セグメントを作る」ユーティリティがあると便利です。
public final class UrlSegments {
private UrlSegments() {}
public static String fieldToSegment(String fieldName) {
String kebab = KebabCases.toKebab(fieldName);
if (kebab == null || kebab.isEmpty()) {
return "";
}
return "/" + kebab;
}
}
Java使い方はこうです。
System.out.println(UrlSegments.fieldToSegment("userName")); // /user-name
System.out.println(UrlSegments.fieldToSegment("userProfile")); // /user-profile
System.out.println(UrlSegments.fieldToSegment("maxRetryCount")); // /max-retry-count
Javaここでのポイントは、「“URL セグメント用”という文脈をメソッド名に刻んでいる」ことです。
中身は単に toKebab を呼んでいるだけですが、fieldToSegment という名前がついているだけで、「これはURLパス用なんだな」と一目で分かります。
例題:Java のプロパティ名からフロントエンド用のキー名を作る
userName → user-name を JSON や設定のキーに使う
フロントエンド側のコードや設定ファイルで、
「キー名はケバブケースで書く」というルールにしているプロジェクトもあります。
その場合、Java のプロパティ名からケバブケースのキー名を作るユーティリティがあると、
バックエンドとフロントエンドの橋渡しがスムーズになります。
public final class FrontKeys {
private FrontKeys() {}
public static String fieldToFrontKey(String fieldName) {
return KebabCases.toKebab(fieldName);
}
}
Java使い方はこうです。
System.out.println(FrontKeys.fieldToFrontKey("userName")); // user-name
System.out.println(FrontKeys.fieldToFrontKey("createdAt")); // created-at
System.out.println(FrontKeys.fieldToFrontKey("profileImageUrl"));// profile-image-url
Javaここでのポイントは、「“フロントエンド用のキー名”という意図を、ユーティリティ名で表現している」ことです。
あとから「やっぱり snake_case にしたい」となったら、fieldToFrontKey の中身だけ差し替えれば、呼び出し側のコードはそのままで仕様変更に追従できます。
例題:CSS クラス名やコンポーネント名をケバブケースにそろえる
UserProfileCard → user-profile-card のような変換
フロントエンドの世界では、CSS クラス名や Web コンポーネント名をケバブケースで書くことが多いです。
user-profile-cardapp-header-bar
Java 側でテンプレートを生成するときに、クラス名やコンポーネント名をケバブケースに変換したい、という場面もあります。
public final class CssNames {
private CssNames() {}
public static String classNameToCss(String className) {
return KebabCases.toKebab(className);
}
}
Java使い方はこうです。
System.out.println(CssNames.classNameToCss("UserProfileCard")); // user-profile-card
System.out.println(CssNames.classNameToCss("AppHeaderBar")); // app-header-bar
Javaここでのポイントは、「PascalCase(クラス名)も camelCase と同じロジックでケバブケースに落とせる」ことです。UserProfileCard → User-Profile-Card → user-profile-card という流れで、
クラス名からそのまま CSS クラス名を作ることができます。
エッジケースと設計のポイント
すでに kebab-case の文字列が来たらどうするか
入力がすでに user-name だった場合、toKebab("user-name") はどうなるか。
正規表現は「小文字+大文字」の境目だけを対象にしているので、user-name はそのまま user-name として返ってきます。
これは、「“すでにケバブケースっぽいものは壊さない”」という意味で、実務的には良い挙動です。
略語(URL, ID, HTTP)をどう扱うか
userID → user-idURLValue → url-value
このあたりは、スネークケースのときと同じく、「略語をどう扱うか」の設計ポイントです。
今の実装では、URLValue → URL-Value → url-value という流れになります。
もし「URLValue は urlvalue にしたい」などの強いルールがあるなら、
略語リストを持っておいて、変換前に置き換える、といった工夫が必要になります。
大事なのは、「ケバブケース変換は“命名規約をコードに落とし込んだもの”であり、プロジェクトごとのルールを反映させていく余地がある」と理解しておくことです。
まとめ:ケバブケース変換ユーティリティで身につけたい感覚
ケバブケース変換は、「Java の世界の名前(userName, UserProfileCard)を、URL やフロントエンドの世界の名前(user-name, user-profile-card)に橋渡しする」ための技です。
押さえておきたい感覚は、まず「小文字(または数字)と大文字の境目に - を挟み、そのあとで小文字に落とす」という二段構えのパターン。
次に、「toKebab を土台にして、fieldToSegment や fieldToFrontKey、classNameToCss のような“文脈付きの薄いラッパー”を用意し、URL・フロント・CSS などの命名規約をユーティリティとして共有する」こと。
もしあなたのコードのどこかに、replaceAll("([a-z])([A-Z])", "$1-$2") のような断片がバラバラに散らばっているなら、
それを題材にして、ここで作った KebabCases や UrlSegments、FrontKeys、CssNames にまとめてみてください。
それだけで、「読みやすくて、再利用できて、バックエンドとフロントエンドの命名がきれいにつながる」文字列処理に、一段レベルアップできます。
