Dynamic route resolver
DynamicRouteResolver
handles dynamic route resolution for the client application.
When a user goes to a page that is not defined in React routing - then the client will ask the back-end for the type of content for that particular url:
- It asks every extension to get "fetch URL priority" from the assigned API DataSource instance
- It sorts API DataSource instances that are able to determine dynamic content type by their "priority"
- It calls
fetchUrl
method on every available API DataSource until it gets a proper response
Example
The simplest example is handling content from shop and blog. Let's say we want to resolve content for /sport.html
class Magento2Api {
getFetchUrlPriority(url) {
// if url ends with .html then it's highly possible that it should be handed by shop
// because it might be a product page under url generated by Magento
return url.endsWith('.html') ? ApiUrlPriority.HIGH : ApiUrlPriority.NORMAL;
}
fetchUrl(obj, args, context, info) {
// implementation of the resolver
}
}
class WordpressApi {
getFetchUrlPriority(url) {
// return just static value so others can be higher or lower
return ApiUrlPriority.NORMAL;
}
fetchUrl(obj, args, context, info) {
// implementation of the resolver
}
}
DynamicRouteResolver
will try to call getFetchUrlPriority(url)
method for both extensions:
- ShopExtension/Magento2Api will return
ApiUrlPriority.HIGH
- BlogExtension/WordpressApi will return
ApiUrlPriority.NORMAL
So in that case DynamicRouteResolver
will call ShopExtension.fetchUrl()
first, if that call returns null
,
it will call BlogExtension.fetchUrl()
second.
By default the API priority order is the order they are added in your server/config/default.json
file. With the first API being checked first. If the priorities are the same this order will be used.
We provide these orders:
@deity/falcon-server-env/src/types.ts
export enum ApiUrlPriority {
HIGHEST = 1,
HIGH = 2,
NORMAL = 3,
LOW = 4,
LOWEST = 5,
OFF = 0
}
DynamicRouteResolver result structure
The correct response must match the following structure:
{
"id": 1,
"path": "/foo.html",
"type": "foo-type",
"redirect": false
}
id
- must represent a unique ID for your back-endpath
- must represent a canonical path for your entity (this will be used for a possible redirection situation)type
- must represent a unique entity type that will be later used byDynamicRoute
component onfalcon-client
redirect
- must set a flag whether the given URL must be redirected to thepath
address (to ensure canonical URL)
Requirements
If any extension should handle dynamic routing it should implement both methods:
getFetchUrlPriority(url)
- accepts url (string
) that should be resolved and returns the priority (number
) for the extensionfetchUrl(obj, args, context, info)
- fetches the data from the remote source or performs any other async logic to determine the type of the given url and returns a correct result ornull
(if the given URL is not determined by your back-end)