Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HTTP] Expose versioned router #153858

Merged
merged 51 commits into from
Apr 3, 2023

Conversation

jloleysens
Copy link
Contributor

@jloleysens jloleysens commented Mar 28, 2023

Summary

Now that we merged #153543, this PR exposes the versioned router for teams to start using. The versioned router will be available on IRouter under a new versioned property.

Primary benefit of this approach is that plugin developers will not need to do anything other than "get" the versioned property to get a versioned router.

Drawback is that this precludes us from passing in additional configuration, like a version, to scope the versioned router instance. For that we would need some kind of createVersionedRouter({ version: ... }). At this point it is not clear this is necessary, we could revisit this decision based on actual usage. Plugin developers could also do something like:

// common const
const MY_API_VERSION: ApiVersion = '1';

// in routes
import {MY_API_VERSION} from '../from/common';
router.versioned.get({ path: ... })
  .addVersion({ version: MY_API_VERSION });

In this way they could get many of the same benefits of a version-scoped version router, with the drawback that they need to pass this in for every route.

TODO

  • Add an integration test for the versioned router

Future work

  • We still need to consider revisiting some of the router design to better support internal cases like adding support for registering a handler for a version range and adding a default version to continue supporting on-prem where introducing versions will be a breaking change

@jloleysens jloleysens added Feature:http Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc release_note:skip Skip the PR/issue when compiling release notes Epic:VersionedAPIs Kibana Versioned APIs v8.8.0 labels Mar 28, 2023
@jloleysens jloleysens self-assigned this Mar 28, 2023
@jloleysens jloleysens requested a review from a team as a code owner March 28, 2023 11:35
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

@jloleysens jloleysens force-pushed the expose-versioned-router branch from 705b8eb to 7b88ded Compare March 28, 2023 11:43
).resolves.toEqual(
expect.objectContaining({
message:
'Version expected at [get] [/my-path]. Please specify a version using the "elastic-api-version" header. Available versions are: "1,2"',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh so polite 😉

@@ -0,0 +1,3 @@
# @kbn/core-http-versioned-router-server-mocks

This package contains the mocks and test utils for core's server-side `http` service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
This package contains the mocks and test utils for core's server-side `http` service
This package contains the mocks and test utils for core's server-side `http` versioned router server.

Copy link
Contributor

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!
I added a couple of comments but nothing that blocks merging.

* Side Public License, v 1.
*/

export function isValidRouteVersion(version: string): boolean {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation won't prevent duplicate versions from being defined. Should we consider adding an option to ensure that each version defined is unique or are we ok with leaving that up to consumers?
Ok, nevermind, we do

@@ -13,10 +13,19 @@ import { Method, VersionedRouterRoute } from './types';

export class CoreVersionedRouter implements VersionedRouter {
private readonly routes = new Set<CoreVersionedRoute>();
public static from({ router }: { router: IRouter }) {
return new CoreVersionedRouter(router);
public static from({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sneaky...I get where the inspiration comes from 😉

@@ -34,6 +35,7 @@ function createRouterMock({ routerPath = '' }: { routerPath?: string } = {}): Ro
patch: jest.fn(),
getRoutes: jest.fn(),
handleLegacyErrors: jest.fn().mockImplementation((handler) => handler),
versioned: createVersionedRouterMock(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the interest of reducing core domains packages footprint, I'd prefer we move the versioned router mock into the router server mocks now rather than piling on yet more tech debt.

Comment on lines +209 to +215
private versionedRouter: undefined | VersionedRouter<Context> = undefined;
public get versioned(): VersionedRouter<Context> {
if (this.versionedRouter === undefined) {
this.versionedRouter = CoreVersionedRouter.from({ router: this });
}
return this.versionedRouter;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on recent discussions around architectural complexity specifically related to core's packages footprint, perhaps we should move the versioned router into the main core-http-router-server-internal package.

* Side Public License, v 1.
*/

export { RouteValidator } from './src/validator';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need another package just for the validator?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enabled us to use this same validation across the router and versioned router packages (otherwise we'd have a circular dep). Collapsing them into one removes this 🙌🏻

@jloleysens jloleysens enabled auto-merge (squash) April 3, 2023 10:22
@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
core 415 417 +2

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/core-http-browser 35 36 +1
@kbn/core-http-router-server-mocks 7 8 +1
@kbn/core-http-server 176 177 +1
@kbn/core-http-versioned-router-server-internal 15 - -15
total -12

Public APIs missing exports

Total count of every type that is part of your API that should be exported but is not. This will cause broken links in the API documentation system. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats exports for more detailed information.

id before after diff
@kbn/core-http-versioned-router-server-internal 2 - -2

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
core 352.4KB 352.5KB +38.0B
Unknown metric groups

API count

id before after diff
@kbn/core-http-browser 109 110 +1
@kbn/core-http-common 4 5 +1
@kbn/core-http-router-server-mocks 7 8 +1
@kbn/core-http-server 439 441 +2
@kbn/core-http-versioned-router-server-internal 15 - -15
total -10

ESLint disabled line counts

id before after diff
securitySolution 432 435 +3

Total ESLint disabled count

id before after diff
securitySolution 512 515 +3

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @jloleysens

@jloleysens jloleysens merged commit ed56403 into elastic:main Apr 3, 2023
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Apr 3, 2023
@jloleysens jloleysens deleted the expose-versioned-router branch April 5, 2023 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Epic:VersionedAPIs Kibana Versioned APIs Feature:http release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v8.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants