Preface
As Kibana has grown, so has the need for a better plugin architecture. What worked with a few developers and dozens of plugins doesn't scale well to hundreds of developers and hundreds of plugins with dependencies between them. To meet Kibana's needs for the long term, it's clear we need to be thinking about things like (just to name a few): formal plugin contracts that are documented and stable across minor versions; enforcing consistent behavior with patterns like a plugin lifecycle and explicit plugin dependencies; and exposing core services that are technology agnostic, to the extent possible.
In 7.2 we've started rolling out this "new platform". At this point the platform is still experimental, but you'll see new APIs in 7.2 and we will be adding more APIs and stabilizing them over the next few minor releases. You will also see a lot of cleanup and refactoring happening as part of this effort, including the gradual removal of AngularJS in favor of React. Bear with us - it will take some time to roll out the platform and migrate existing plugins, but once all is done Kibana will scale well into the future!
Prefer third-party plugin development in plugins
instead of kibana-extra
This change switches preferred third-party plugin development from ../kibana-extra
, instead favoring the plugins
directory in the Kibana root. By association, @kbn/pm
has the --skip-kibana-extra
flag renamed to --skip-kibana-plugins
.
via #31748
ui/public
cleanup
Relocated modules
In preparation for Kibana's upcoming new platform, we are in the process of migrating away from the ui/public
directory. Over time, the contents of this directory will be either deprecated or housed inside a parent plugin. If your plugin imports from any of the following ui/public
modules, you will need to update your import statements as indicated below, so that you are pulling these modules from their new locations.
ui/search_bar
// deprecated
import 'ui/search_bar';
// new location
import { data } from 'plugins/data';
data.search.loadLegacyDirectives();
// deprecated
import { SearchBar } from 'ui/public/search_bar/components';
// new location
import { data } from 'plugins/data';
const { SearchBar } = data.search.ui;
ui/query_bar
// deprecated
import 'ui/query_bar';
// new location
import { data } from 'plugins/data';
data.query.loadLegacyDirectives();
// deprecated
import { QueryBar } from 'ui/public/query_bar/components';
// new location
import { data } from 'plugins/data';
const { QueryBar } = data.query.ui;
via #35683
Expose an HTTP-request browser client
The HTTP browser client now exposes methods for simplifying HTTP requests. The long-term goal of this service/client is to replace the legacy kfetch
service. This also swaps out the internals of kfetch
for this new service, meaning legacy and new platform plugins are both backed by this functionality.
From a sat up HttpService
, there are now 5 additional methods:
http.fetch(path, options)
: This has an API comparable towindow.fetch
with the addition of a few custom options, status code error handling, default HTTP header additions, and automatic body parsing resolution for JSON and NDJSON.http.get(path, options)
: TheGET
-enforced shorthand forhttp.fetch()
.http.post(path, options)
: ThePOST
-enforced shorthand forhttp.fetch()
.http.put(path, options)
: ThePUT
-enforced shorthand forhttp.fetch()
.http.delete(path, options)
: TheDELETE
-enforced shorthand forhttp.fetch()
.http.patch(path, options)
: ThePATCH
-enforced shorthand forhttp.fetch()
.
via #35486
Renamed AggParam disabled
to shouldShow
In case you're writing a custom AggConfig
- which we DO NOT recommend - a parameter could have a disabled
callback, which if returning true
would hide the control of this parameter in the visualize editor. This callback is now called shouldShow
and must return false
to be hidden. That way we reduce confusion with controls that can actually have a disabled state.
via #35139
Removed customInterval
from AggParam, changed interval
value
We removed customInterval
from AggParam. Now the custom interval is specified in the interval
property. Also now predefined intervals such as Yearly
, Daily
, etc., are stored as a keys in the interval
property, e.g. interval: 'y'
, interval: 'd'
, interval: '2s'
.
via #34991
Regex AggParam
type removed
It is no longer possible to specify an AggParam
of type regex
. You may be using it when providing your own AggType
(which we DO NOT recommend) and consider a stable API. There will be more breaking changes to custom AggTypes
in the upcoming versions.
via #34530
Autoload Cleanup & Angular Removal
Removed autoload items
As we work to gradually remove implicit dependencies across the Kibana core, the following items are no longer being imported by ui/autoload
. If you use ui/autoload
and your plugin relies on any of the following items, please import them explicitly where they are needed.
$listen
(via #33765)bind
(via #33765)bound_to_config_obj
(via #33765)css-truncate
(via #33765)debounce
(via #33765)doc_title
(via #33765)events
(via #33765)fancy_forms
(via #33765)filter_bar
(via #33765)filter_manager
(via #33765)index_patterns
(via #33765)inequality
(via #33765)input-focus
(via #33765)json-input
(via #33765)kbn_top_nav
(via #33765)paginate
(via #33765)paginated-selectable-list
(via #33765)parse_query
(via #33765)persisted_log
(via #33765)query_bar
(via #33765)saved_object_save_as_checkbox
(via #33765)saved-object-finder
(via #33765)timefilter
(via #33765)timepicker
(via #33765)
Removed unused Angular items
In the process of removing Angular from the Kibana core, the following unused items have been deleted. If you have used any of those in your plugin and want to keep using them, please copy over the source from the previous Kibana version directly into your plugin code.
Note: These have also been removed from ui/autoload
.
Factories
dirtyPrompt
,ui/dirty_prompt
(via #34060)
Filters
commaList
(via #33807)label
(via #33807)markdown
(via #33807)matchAny
(via #33807)startFrom
(via #33807)trustAsHtml
(via #33807)sortPrefixFirst
(via #34060)unique
(via #33807)
Directives
accordion
(via #33244)accordionGroup
(via #33244)accordionHeading
(via #33244)accordionTransclude
(via #33244)alert
(via #33564)autoSelectIfOnlyOne
(via #33372)bar
(via #33585)btnCheckbox
(via #33244)btnRadio
(via #33373)callOut
(via #33244)checkBox
,ui/check_box
(via #34060)clickFocus
(via #33372)collapse
(via #33244)colorPicker
(via #33244)confirmClick
(via #33244)confirmModal
(via #33244)dismissOnTimeout
(via #33244)documentationHref
(via #33372)draggableContainer
,ui/draggable
(via #34060)draggableHandle
,ui/draggable
(via #34060)draggableItem
,ui/draggable
(via #34060)dropdown
(via #33520)dropdownToggle
(via #33520)elasticTextarea
(via #33244)fileUpload
(via #33244)focusOn
(via #33244)icon
(via #33244)inputBaseSixtyFour
(via #33244)inputDatetime
(via #33244)inputNumber
(via #33372)jsonInput
(via #34060)kbnAggTable
,ui/agg_table
(via #34060)kbnSrc
(via #34060)kbnInfiniteScroll
(via #33765)kbnNumberList
,ui/number_list
(via #34060)kbnScrollButton
(via #33372)kbnTooltip
,ui/tooltip
(via #34060)pager
(via #33564)paginatedTable
,ui/paginated_table
(via #34060)pagination
(via #33564)parseQuery
,ui/parse_query
(via #34232)progress
(via #33585)progressbar
(via #33585)rating
(via #33244)sortableColumn
,ui/sortable_column
(via #34060)stringToNumber
(via #33244)toggleButton
,ui/toggle_button
(via #34060)togglePanel
,ui/toggle_panel
(via #34060)uiSelectFocusOn
(via #33244)validateAgg
(via #33372)validateCidr-mask
(via #33372)validateDateInterval
(via #33372)validateDateMath
(via #33372)validateIndexPattern
(via #33244)validateIp
(via #33372)validateJson
(via #33765)validateLowercase
(via #33244)tabset
(via #33425)tab
(via #33425)timepicker
(via #33564)tooltipPopup
(via #33564)tooltipHtmlUnsafePopup
(via #33564)
via #33289
Encourage static i18n import
Kibana is in the process of moving away from AngularJS and as part of that we are starting the process of removing AngularJS specific i18n
code.
Going forward, we encourage using i18n.translate()
by statically importing i18n
from @kbn/i18n
wherever possible in your AngularJS code. Avoid using the i18n
filter and the i18n
service injected in controllers, providers, and services. These will be removed in a future release.
In ReactJS, Avoid using injectI18n
and rely on i18n.translate()
instead.
via #37858
Get rid of Handlebars support in i18n tools
i18n tooling no longer supports parsing labels from handlebar files. Since we don't use i18n in handlebars in Kibana anymore it'd make sense to get rid of i18n Handlebars support as well. This will make i18n tools code lighter, easier to maintain and slightly improve i18n validation/extraction speed as we'll be skipping .hbs
files.
via #32190
npm dependencies
Remove unused pivotal-ui package
via #30975
Upgrade @babel/* dependencies
Updated Babel dependencies as babel has fixed several issues in their TS plugin that allows us to not exclude TS files with some specific syntax from i18n_check
that relies on babel/parser
and friends.
via #32031
Introduce UI PluginsService
The experimental new platform now supports plugins in the browser. The API for defining plugins mirrors the interface for server-side plugins. New platform plugins can enable a client-side plugin by defining an entry point my_plugin/public/index.ts
and adding the "ui": true
flag in their my_plugin/kibana.json
file.
The entry point for the plugin should export a single plugin
function that returns an initialized plugin with the required setup
, start
, and stop
functions:
// my_plugin/public/index.ts
import { CoreSetup, CoreStart, Plugin, PluginInitializer } from 'kibana/public';
export const plugin: PluginInitializer<MyPluginSetup, MyPluginStart> = () =>
new MyPlugin();
interface MyPluginSetup {
foo: string;
}
interface MyPluginStart {
bar(): string;
}
class MyPlugin implements Plugin<MyPluginSetup, MyPluginStart> {
setup(core: CoreSetup) {
return { foo: 'bar' };
}
start(core: CoreStart) {
return {
bar() { return 'baz' }
};
}
stop() { }
}
Any value returned by your plugin's setup
and start
functions will be provided as dependencies for any plugins that depend on your plugin via the requiredPlugins
and optionalPlugins
options in a plugin's kibana.json
file.
via #32672
Expose New Platform core services to the legacy UI
Kibana is in process of stabilizing the platform APIs. The client side core services are quite different from existing ones and were heavily refactored. If you want to play around with experimental APIs, please use
import { getNewPlatform } from 'ui/new_platform';
const newPlatform = getNewPlatform();
where newPlatform
exposes:
via #32480
Expose New Platform core services and plugins contracts to the legacy server
Kibana is in process of stabilizing the platform APIs. During this release, our primary focus was on formalizing API for main core services. Although this is still an experimental API, you can have access to updated elasticsearch and http services on the server side via kbnServer.newPlatform
that exposes:
- coreContext.logger: LoggerFactory
- setup.core: CoreSetup
- start.core: CoreStart
via #32468
Overlay core service
The new (in-development) Kibana Plugin Platform now includes an Overlays service for opening flyouts and modals with EUI. New plugins can access this service via the overlays
key on the CoreStart
interface passed to plugins in their start
lifecycle function. The Overlays service ensures that only a single modal or flyout is present on the page, manages the lifecycle of the overlay, and provides APIs for closing overlays and being notified when the overlay was closed by a user.
via #34261
Restrict import from core & plugin internals for ts files
New platform plugins and core services should have clear boundaries and declare their export contract explicitly. We introduced relevant linter rules in order to enforce this convention and prevent arbitrary exports from module internals. Now import is only allowed:
- for core service - from the root of the system.
src/core/server
,src/core/public
- for plugins - from the root of the plugin.
plugins/pluginName/server
,plugins/pluginName/public
.
via #34688
Added server side API for importing saved objects
New endpoints /api/saved_objects/_import
and /api/saved_objects/_resolve_import_errors
now exists to import saved objects.
via #32158
Add user_action app for gathering telemetry on user actions
Added a new API endpoint POST /user_action/<app>/<action_type>
which is used to add UI telemetry to track user actions. This API that is not intended for external use and will likely change in the next versions.
via #31543
Added server side API for exporting saved objects
A new endpoint /api/saved_objects/_export
now exists to export saved objects.
via #30326
Saved Objects
The location of the classes SavedObjectLoader
and SavedObjectProvider
which are used to load and save saved objects has changed. If you are depending on these classes in your plugin implementation, you have to update the import paths as follows:
- from
import { SavedObjectProvider } from 'ui/courier';
toimport { SavedObjectProvider } from 'ui/saved_objects/saved_object';
- from
import { SavedObjectLoader } from 'ui/courier/saved_object/saved_object_loader';
toimport { SavedObjectLoader } from 'ui/saved_objects';
via #30241
Introduce Elasticsearch service
We've introduced an Elasticsearch service to the new experimental plugin platform. This service allows new platform plugins to get elasticsearch-js
clients for querying Elasticsearch on the server.
To access the new Elasticsearch service from a new platform plugin:
class MyPlugin {
start(core, plugins) {
core.elasticsearch.dataClient$.subscribe(client => {
// query Elasticsearch
});
}
}
Clients are exposed via an Observable interface to reflect the possibility that the connection configuration changes while the server is running.
via #28344