Tutorial | React frontend webapp#
React webapps are not natively supported by Dataiku, but it’s still possible to integrate a React application into Dataiku with the help of a dev plugin and a visual webapp.
In this article, we’ll discuss a few ways you can do this.
Quick start#
All of the steps below are implemented in a demo plugin found in this repository.
You can choose to Fetch from Git repository, convert it into a dev plugin, and modify it according to your needs instead of creating a new plugin from scratch.
After creating the plugin from git, the demo React app needs to be built. From the $DATADIR/plugins/dev/react/resource/my-app
run:
npm install && npm run build
After this step, you can create a new visual webapp inside a project:
After modifying the source code of the React app, it needs to be compiled by re-running:
npm run build
Manual dev plugin creation#
Create a dev plugin on your Dataiku instance.
Create the following file structure.
where:
resource/my-app
- your react application directory.webapps/react/app.js
- an empty file required by Dataiku.webapps/react/body.html
- a symlink to the resource/my-app/build/index.html.webapps/react/webapp.json
- a webapp config, for example.
{ "meta": { "label": "Test react app", "description": "", "icon": "icon-puzzle-piece" }, "baseType": "STANDARD", // WARNING: do not change "hasBackend": "false", "noJSSecurity": "false", "standardWebAppLibraries": ["jquery","dataiku"], "params": [], "roles": [ /* {"type": "DATASET", "targetParamsKey": "input_dataset"} */ ] }
Finally, add
"homepage": "../../resource/my-app/build"
to yourresource/my-app/package.json
.
That’s it! Now you just need to reload the webapp from the plugin actions dropdown, and once your React app is built, you can create a new visual webapp in your project.
Using JSX to develop your app#
You can use JSX to develop your app. However, you would need to build it first so that Dataiku could serve compiled javascript files whenever the webapp is opened.
Also, note that you won’t be able to leverage Webpack dev server. Instead, you’ll need to recompile the webapp after changes.
The build should be run manually from the:
$DATADIR/plugins/dev/YOUR_PLUGIN_NAME/resource/YOUR_WEBAPP_NAME
Using a Python-lib folder#
Python-lib is a directory that may contain Python code that is shared between different webapp backends. In this case, it’s empty so you can ignore it to reduce confusion.
In general, if you need a Python backend for your webapp, you need to create a backend.py
file defining the endpoints. Here’s an example of how it can be done.
Multiple webapps in one plugin and IDEs for development#
You can have multiple webapps in one plugin. Just create another directory next to webapps/react
with a similar structure.
Warning
Make sure you don’t forget to add a webapp.json
and at least modify meta property in it.
For the development process, it’s recommended to create a plugin first and add a simple React webapp into it. Then you’re not limited to only coding inside Dataiku, you can either:
Open
$DATADIR/plugins/dev/YOUR_PLUGIN_NAME/resource/YOUR_WEBAPP_NAME
with your favorite IDE and continue developing the app from it, orUse our VSCode integration to edit your plugin code.
In both cases, you are free to develop the webapp completely outside of Dataiku (just by starting the dev server manually from the webapp dir). But to test the API requests served by the python backend, you would need to compile the app and open it from Dataiku.
Creating a backend for your React webapp#
If you’d like to have a backend for your React webapp, here are the steps you’d need to take.
Note
The instructions below assume you have followed the instructions above and created a plugin. However, you can follow the same steps even if you’ve just created a webapp without a plugin.
Modify
$DATADIR/plugins/installed/PLUGIN/webapps/WEBAPP/webapp.json
to contain."hasBackend": "true"
Add
$DATADIR/plugins/installed/PLUGIN/webapps/WEBAPP/backend.py
, for example:import dataiku from flask import request @app.route('/first_api_call') def first_call(): return json.dumps({"status": "ok", "data": 123})
If you need to contact the Dataiku API, you can use the dataiku
library imported in the beginning.
Modify your react component to send AJAX requests (not the part around
first_api_call
).import React from 'react'; import logo from './logo.svg'; import './App.css'; function App() { function handleClick(e) { console.log('The link was clicked.'); window.$.getJSON(window.getWebAppBackendUrl('first_api_call'), function(data) { const output = window.$('<pre />').text('Backend reply: ' + JSON.stringify(data)); window.$('body').append(output) }); } return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> <code onClick={handleClick}>Click me!</code> </header> </div> ); } export default App;
jQuery
and getWebAppBackendUrl
are added to your page automatically by Dataiku. In order to overcome the React compilation issues, you would have to refer to them from a window object.
Important
Don’t forget to restart Dataiku after applying all of the modifications and start the newly created backend when running the webapp.
Appendix#
Whenever a user opens a webapp, including the one created in a plugin using React, Dataiku adds some utility code including the window.getWebAppBackendUrl
function definition. This happens after the React application is loaded. If your application relies on some data from the backend during initialization, you may face an issue where window.getWebAppBackendUrl
is not available yet.
One solution could be to add conditional rendering to the root component of your app.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
rendered: false,
dataiku: undefined
};
window.$(document).ready(() => {
this.setState({ dataiku: window.dataiku });
this.setState({ rendered: true });
}
);
}
render() {
return (
<div>
{this.state.rendered && <h1>DKU API ready: {this.state.dataiku.getWebAppBackendUrl && 'YES' }</h1>}
</div>
);
}
}
What’s next?#
You can watch this tutorial for more guidance: Configuring a backend for React webapp in Dataiku.