* [APM] @kbn/typed-router-config * [APM] typed route config * Breadcrumbs, wildcards * Migrate settings, home * Migrate part of service detail page * Migrate remaining routes, tests * Set maxWorkers for precommit script to 4 * Add jest types to tsconfigs * Make sure transaction distribution data is fetched * Fix typescript errors * Remove usage of react-router's useParams * Add route() utility function * Don't use ApmServiceContext for alert flyouts * Don't add onClick handler for breadcrumb * Clarify ts-ignore * Remove unused things * Update documentation * Use useServiceName() in ServiceMap component
3.7 KiB
APM Plugin Routing and Linking
Routing
This document describes routing in the APM plugin.
Server-side
Route definitions for APM's server-side API are in the server/routes directory. Routes are created with the createRoute
function. Routes are added to the API in the createApmApi
function, which is initialized in the plugin start
lifecycle method.
The path and query string parameters are defined in the calls to createRoute
with io-ts types, so that each route has its parameters type checked.
Client-side
The client-side routing uses @kbn/typed-react-router-config
, which is a wrapper around React Router and React Router Config. Its goal is to provide a layer of high-fidelity types that allows us to parse and format URLs for routes while making sure the needed parameters are provided and/or available (typed and validated at runtime). The history
object used by React Router is injected by the Kibana Platform.
Routes (and their parameters) are defined in public/components/routing/apm_config.tsx.
Parameter handling
Path (like serviceName
in '/services/:serviceName/transactions') and query parameters are defined in the route definitions.
For each parameter, an io-ts runtime type needs to be present:
{
route: '/services/:serviceName',
element: <Outlet/>,
params: t.intersection([
t.type({
path: t.type({
serviceName: t.string,
})
}),
t.partial({
query: t.partial({
transactionType: t.string
})
})
])
}
To be able to use the parameters, you can use useApmParams
, which will automatically infer the parameter types from the route path:
const {
path: { serviceName }, // string
query: { transactionType } // string | undefined
} = useApmParams('/services/:serviceName');
useApmParams
will strip query parameters for which there is no validation. The route path should match exactly, but you can also use wildcards: useApmParams('/*)
. In that case, the return type will be a union type of all possible matching routes.
Previously we used useUrlParams
for path and query parameters, which we are trying to get away from. When possible, any usage of useUrlParams
should be replaced by useApmParams
or other custom hooks that use useApmParams
internally.
Linking
Raw URLs should almost never be used in the APM UI. Instead, we have mechanisms for creating links and URLs that ensure links are reliable.
In-app linking
For links that stay inside APM, the preferred way of linking is to call the useApmRouter
hook, and call router.link
with the route path and required path and query parameters:
const apmRouter = useApmRouter();
const serviceOverviewLink = apmRouter.link('/services/:serviceName', { path: { serviceName: 'opbeans-java' }, query: { transactionType: 'request' }});
If you're not in React context, you can also import apmRouter
directly and call its link
function - but you have to prepend the basePath manually in that case.
We also have the getAPMHref
function and APMLink
component, but we should consider them deprecated, in favor of router.link
. Other components inside that directory contain other functions and components that provide the same functionality for linking to more specific sections inside the APM plugin.
Cross-app linking
Other helpers and components in the Links directory allow linking to other Kibana apps.