-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[data views] data_views REST API #112916
[data views] data_views REST API #112916
Conversation
💚 Build Succeeded
Metrics [docs]
History
To update your PR or re-run it, just comment with: |
@elasticmachine merge upstream |
Pinging @elastic/kibana-app-services (Team:AppServicesSv) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if we really want to rework this approach right now, but here are some things I am looking at:
- Seems like because of dynamic validation schema building we lost a type inference on body
- I find this a bit fragile, how we have to build a response object and keys in the response based on
serviceKey
. Also even${serviceKey}_id
in some cases - Same for
res.ok(serviceKey === SERVICE_KEY_LEGACY ? legacyResponse : response);
I wonder if instead, we should add one more layer abstracting REST API logic:
Something like:
export const registerLegacyCreateRuntimeFieldRoute = (
router: IRouter,
getStartServices: StartServicesAccessor<
DataViewsServerPluginStartDependencies,
DataViewsServerPluginStart
>
) => {
router.post( {
path: '/api/index_patterns/index_pattern/{id}/runtime_field',
validate: {...}
}),
(ctx, req, res) => {
const id = req.params.id;
const { name, runtimeField } = req.body;
const dataView = dataViewRestApiService.addRuntimeField(
ctx,
getStartServices,
{id, name, runtimeField}
)
return {// oldResponseStructure }
})
export const registerCreateRuntimeFieldRoute = (
router: IRouter,
getStartServices: StartServicesAccessor<
DataViewsServerPluginStartDependencies,
DataViewsServerPluginStart
>
) => {
router.post( {
path: '/api/data_views/data_view/{id}/runtime_field',
validate: {...}
}),
(ctx, req, res) => {
const id = req.params.id;
const { name, runtimeField } = req.body;
const dataView = dataViewRestApiService.addRuntimeField(
ctx,
getStartServices,
{id, name, runtimeField}
)
return {// newResponseStructure }
})
Basically instead of wrapping abstraction around routes,
We will have routes separate with a bit of copy-paste there. We will keep validation schemas static. And we will have there only params extraction and response building.
Everything else will happen in a new service which will be shared between new and legacy.
I think this will also help us to build new versions of routes. We will keep request and response processing there but have business logic shared.
Wonder what are you thoughts on this and on the current approach in general
); | ||
const indexPattern = await indexPatternsService.createAndSave( | ||
body[serviceKey] as DataViewSpec, | ||
body.override as boolean, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like type inference from schema got broken because of the dynamic schema approach we took here? :(
@Dosant You're correct in your observation that type inference has been lost. That said, I think its possible to address it. I see this as a functional problem with the code. // [serviceKey]: indexPatternSpecSchema,
data_view: serviceKey === SERVICE_KEY ? indexPatternSpecSchema : schema.never(),
index_pattern:
serviceKey === SERVICE_KEY_LEGACY ? indexPatternSpecSchema : schema.never(), If I specify the two potential keys it no longer stomps on the other key types. When you say that the code is fragile, I think you mean that any changes to the one API and not the other will either entail the unwanted addition of further conditionals OR a wholesale separation of the code. I agree, but I think its an acceptable tradeoff. The differences are currently simple so further separation of the code would not be difficult. Further, the code may go untouched for a good long while before this is a concern. Taking another look at the code, the business logic is often just one or two lines. This is mostly wrapper code, which makes sense considering what it is. I need to look at this with fresh eyes tomorrow. |
@Dosant I've taken a closer look and haven't found further opportunities for improvement considering the tradeoffs mentioned above. |
@elasticmachine merge upstream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM,
when we update docs, need not forget to include the change about runtime fields fields
@elasticmachine merge upstream |
@elasticmachine merge upstream |
💚 Build Succeeded
Metrics [docs]Public APIs missing comments
Unknown metric groupsAPI count
References to deprecated APIs
History
To update your PR or re-run it, just comment with: |
Creation of data_views REST API which is largely a duplication and rename of the index_patterns REST API.
The PR is quite large but the changes are minor:
route
andserviceKey
(index_pattern
ordata_view
, used for submitting or returning info) are passed as arguments.data_view
versions return a field array instead. This is because runtime fields will soon support returning multiple fields (object runtime fields)index_pattern
anddata_view
versionsCloses #113422