Skip to main content
Version: v0.x

How do Routes match requests?

Request matching basics

This article descibes how Proxyflare matches an incoming request to a Route in your Configuration using the concept of pathname score.

Let's test your intuition with a basic setup.

Proxyflare is installed on proxyflare.works with the Configuration below and a request arrives — GET https://proxyflare.works/api/users/john.

Each Route matches the incoming request. Which Route does Proxyflare run?

functions/_middleware.ts
// incoming request: GET https://proxyflare.works/api/users/john

const routes: Route[] = [
{
from: { pattern: "proxyflare.works/api/*" },
...
},
{
from: { pattern: "proxyflare.works/api/users/*" },
...
},
]
Answer

The second route runs! But why?

Proxyflare sorts each Route by the pathname score of Route["from.pattern"]. The second route runs because it contains more pathname parts.

How pathname score works

If an incoming request matches multiple Routes, Proxyflare runs the Route with the higher pathname score. Every Route is assigned a pathname score using the value of Route["from.pattern"].

Assigning pathname depth

Pathname score increases with pathname depth. The more forward-slash / separated path slugs in Route["from.pattern"], the higher the rank.

For example, Route["from.pattern"]=ex.com/shallow/deeper has a pathname depth of two with path slugs shallow and deeper.

Pathname depthPathname scoreRoute["from.pattern"]
33ex.com/shallow/deeper/deep
22ex.com/shallow/deeper
11ex.com/shallow

Breaking pathname depth ties

Given two patterns with the same pathname depth, rank is allocated by last slug length. For example, given Route["from.pattern"]=ex.com/shallow/deep and Route["from.pattern"]=ex.com/shallow/deeper, the latter wins because deeper is longer slug than deep.

Pathname depthLast slug lengthPathname scoreRoute["from.pattern"]
262ex.com/shallow/deeper
241ex.com/shallow/deep

Proxyflare supports wildcard patterns for matching subrequests on a particular pathname. Some pathname patterns would be identical when wildcards are removed. In this case, pattern type is used to break the tie:

  1. Absolute path ex.com/shallow
  2. Inline wildcard ex.com/shallow*
  3. Slash wildcard ex.com/shallow/*
Pathname depthLast slug lengthPattern typePathname scoreRoute["from.pattern"]
17absolute3ex.com/shallow
17inline *2ex.com/shallow*
17slash *1ex.com/shallow/*

In other words, if multiple Routes are identical after wildcards are removed, the absolute path outranks the inline wildcard and the inline wildcard outranks the slash wildcard.

TLDR

The Route with the highest pathname depth wins.

If multiple routes have the same pathname depth, the longer last path slug wins.

If multiple routes have the same last path slug after removing wildcards, absolute paths beat inline wildcards and inline wildcards beat slash wildcards.

The following table shows this ranking strategy with complex Route["from.pattern"]s listed by pathname score. The last column shows an incoming request that would match each pattern.

Pathname scoreRoute["from.pattern"]Example Matching Request
14ex.com/shallow/deeperex.com/shallow/deeper
13ex.com/shallow/deeper*ex.com/shallow/deeper-in
12ex.com/shallow/deeper/*ex.com/shallow/deeper/down
11ex.com/shallow/deepex.com/shallow/deep
10ex.com/shallow/deep*ex.com/shallow/deep-in
9ex.com/shallow/deep/*ex.com/shallow/deep/down
8ex.com/shallowerex.com/shallower
7ex.com/shallower*ex.com/shallower-yet
6ex.com/shallower/*ex.com/shallower/still
5ex.com/shallowex.com/shallow
4ex.com/shallow*ex.com/shallow-lakes
3ex.com/shallow/*ex.com/shallow/water
2ex.com/ex.com/
1ex.com/*ex.com/anything-still-unmatched
Tip

Set the Configuration["global.debug"] flag to attach a x-proxyflare-proxied-pathname response header to matched requests. This debug header contains the matched pathname.