Hone logo
Hone
Problems

Route Matcher in JavaScript

This challenge asks you to implement a route matcher in JavaScript. A route matcher takes a URL path and a set of defined routes and determines if the URL path matches any of the routes. This is a fundamental component in web frameworks and APIs for routing requests to the correct handlers.

Problem Description

You need to create a function matchRoute(url, routes) that takes a URL path (string) and an array of route definitions as input. Each route definition is an object with a path property (string) and an optional method property (string). The function should return the first matching route object if a match is found, otherwise it should return null.

A route matches if:

  1. The URL path starts with the route's path.
  2. If a method is specified in the route, the request method (obtained from the URL - assumed to be the HTTP method, e.g., "GET", "POST") must match the route's method. For simplicity, assume the URL is always in the format [method] [path]. Extract the method by splitting the URL string by a space.
  3. If no method is specified, any method is considered a match.

The matching should be based on prefix matching. For example, if the route path is /users, it should match /users, /users/123, and /users/profile.

Edge Cases to Consider:

  • Empty URL or routes array.
  • Route paths starting with a wildcard character (e.g., *). Wildcards should match any subsequent path segment. (This is an optional extension - see Notes).
  • Routes with empty paths.
  • Case sensitivity of the URL path and route paths. (Assume case-sensitive matching for this challenge).
  • Invalid URL format (no space separating method and path).

Examples

Example 1:

Input: url = "GET /users", routes = [{ path: "/users" }, { path: "/products", method: "POST" }]
Output: { path: "/users" }
Explanation: The URL path "/users" matches the first route's path. The method "GET" doesn't matter since the route doesn't specify a method.

Example 2:

Input: url = "POST /products", routes = [{ path: "/users" }, { path: "/products", method: "POST" }]
Output: { path: "/products", method: "POST" }
Explanation: The URL path "/products" matches the second route's path, and the method "POST" matches the route's specified method.

Example 3:

Input: url = "GET /users/123", routes = [{ path: "/users" }, { path: "/products", method: "POST" }]
Output: { path: "/users" }
Explanation: The URL path "/users/123" is a child path of "/users". The first matching route is returned.

Example 4:

Input: url = "GET /", routes = [{ path: "/users" }, { path: "/" }]
Output: { path: "/" }
Explanation: The URL path "/" matches the second route's path.

Constraints

  • url will be a string.
  • routes will be an array of objects.
  • Each route object will have a path property (string).
  • Each route object may have a method property (string).
  • The length of the routes array will be between 0 and 100.
  • The length of the url string will be between 0 and 200.
  • The method in the URL and route (if present) will be a string of length between 1 and 10.
  • Route paths will be strings of length between 1 and 50.
  • Performance: The function should ideally complete within 100ms for a typical input.

Notes

  • Consider using string methods like startsWith() for efficient prefix matching.
  • You can assume the URL is always in the format [method] [path].
  • This challenge focuses on the core matching logic. Error handling for invalid URLs is not required.
  • Optional Extension (for extra challenge): Implement wildcard support in route paths. For example, a route with path: "/users/*" should match /users, /users/123, and /users/profile. The * should match any sequence of characters. You'll need to handle this in your matching logic.
  • Think about how to handle the case where multiple routes match. The problem statement specifies returning the first matching route.
  • Focus on clarity and readability of your code. Well-structured code is easier to understand and maintain.
Loading editor...
javascript