Skip to content
This repository has been archived by the owner on Jan 20, 2023. It is now read-only.

Latest commit

 

History

History
110 lines (56 loc) · 11.8 KB

GUIDE.markdown

File metadata and controls

110 lines (56 loc) · 11.8 KB

Advanced Guide to the Grove React-Redux-Node Template

This Grove Project Template specifies a Project consisting of two Grove Applications:

In addition, it provides an ml-gradle installation in the marklogic directory. The default ml-gradle configuration matches the other defaults in this Template, but any changes to the application template at the moment have to also be changed manually in the ml-gradle configuration. We will likely improve this story soon.

The UI and middle-tier Applications are yours to extend using the tools of their respective ecosystems. In the future, you may be able to install Grove Plugins or even swap in Vue Grove UI, or a Java Grove middle-tier, so long as they meet the API contracts defined by Grove.

Installing the template

The recommended way to install this template is using the grove-cli as described in the README.

Note that while, at the moment, you can git clone --recursive this repository and get a working application, that is an implementation detail and is likely to change. The grove-cli is the one supported way to turn this Template into a Project.

A Modular Template

It is worth noting that this Template is designed to be highly modular. You can adopt various parts without the others - and, indeed, without using Grove itself.

These include:

  • reusable front-end React components

    Our React components can be used without Redux, so long as you pass them the properties and functions that they require. You can even add React components into an existing application that does not use React elsewhere.

  • Redux modules to manage client-side state and handle interactions with a middle-tier

    Our Redux components could be used with a different front-end framework, including AngularJS and Vue.js. We have proved this ourselves, by creating reference applications in AngularJS and Vue.js which reuse the grove-search-redux module.

  • a default and replaceable Node middle-tier using Express.js.

    Similarly, the Node middle tier could be swapped out for one implemented in Java or, indeed, in MarkLogic itself.

Learning to Customize and Extend Your Application

If your project based on this template works for you as-is, great. But odds are good that you will need to customize or extend it. This is a guide to learning how to do that.

The Front-End: React + Bootstrap

One part of your project you may soon want to update is the UI Application, which lives inside the ui directory of Applications generated by this Template.

#### Built on Create-React-App

In this template, we have leveraged Facebook's create-react-app project, rather than creating and maintaining a modern javascript build environment ourselves. create-react-app provides most of the dependencies and configuration needed to do things like run tests, start a development server, and create a production build. Best of all, when the create-react-app updates their project, it is a simple process to update this application to take advantage.

This indirection could cause some confusion. For example, Webpack is central to build processes, but you may be surprised to see that there is no ui/webpack.config.js file. Instead, create-react-app provides the necessary configuration.

This optimizes away most maintainance of our build process over time and creates a common experience for developers across all Grove React apps. There are many ways to customize what is provided. If, however, you find that you need to separate from create-react-app, there is a way to "eject". Careful, though, because that is a one-way step: You will not be able to stay up-to-date with create-react-app updates over time.

Styling (Look and Feel)

Grove React components are styled using Bootstrap 3. There are many themes available to update the look-and-feel of standard Bootstrap classes.

You could, of course, also provide your own custom CSS in ui/src/index.css.

If you find yourself editing React components, take a look at the documentation for React-Bootstrap, which is what we use to provide Bootstrap-styled components.

Editing or Writing React Presentational Components

We selected React in large part because there are many excellent resources for learning to work with the framework (as well as extending it). To learn React, you should start with the official React docs or tutorial, which will introduce you to the framework in a highly intuitive way.

The presentational React components are provided through the grove-react-ui. These components are 'dumb', presentation-only React components that render html based on provided properties and invoke callback functions based on user interaction. (Here is a good article on the useful pattern of dividing an application between 'dumb', presentational components and 'smart' containers. We lean heavily on this pattern in Grove.)

In particular, the React components are unaware of the Redux layer. They simply define properties and functions that they expect to be passed to them. They are only responsible for rendering an appropriate view based on those properties and for wiring user actions to the passed-in functions.

The Grove React components are imported and used in ui/src/App.js and ui/src/containers/SearchContainer.js.

If you want to change the React components, you can provide your own components and import those instead. (Your components may also import some of the grove-core-react-components, so you don't have to recreate everything.)

Client-Side State-Management System (using Redux)

Redux provides a popular pattern to manage state in a single-page Web or mobile application. Like React, it is surrounded by a rich ecosystem, and the official Redux docs are the best starting point for learning about it. Please read those first! We will not try to explain all of Redux here.

This template provides Redux modules organized as 'ducks'. This means that your application can import reducers defined in the Redux module to respond to actions and manage part of your Redux state tree.

Each module exposes selectors that your application can use to get information from that part of the state tree.

Each module also defines actionCreators that your application can call to, for example, run a search. We are using the redux-thunk library to handle asynchronous actions, as described in the Redux docs.

Finally, each Redux module currently defines an interface to the service tier (for example, for communicating with MarkLogic or other Web services to run a search). It calls out to a specific endpoint and expects a certain shape of response. We are still fleshing this out, but the goal is to make the service tier completely swappable, so long as an adapter is provided that provides the Redux module the interface that it requires.

At the moment, we provide three modules as part of the grove-react-ui: search, crud, and user.

Your application needs to provide some glue to connect the Redux modules to the 'dumb' React components, which are not aware of Redux. This Template does that, in ui/src/App.js and ui/src/containers/, which contains 'smart' React containers that are Redux-aware and pass the appropriate properties and functions down to the 'dumb' React components.

If you need to modify the way selectors or actionCreators work, you can create decorator functions that call out to them but also do other work. Then, pass your decorator functions down to the 'dumb' React components instead. Or you could define your own actionCreators or selectors from scratch.

If you are extending this application, you will have to decide whether you are adding new state and whether it should be managed by Redux or not. It is not mandatory. Redux adds some indirection, complexity and constraints in exchange for making state easier to reason about and for assistance integrating different parts of your application. The author of Redux has a good article exploring these trade-offs, called, "You Might Not Need Redux."

For example, if you create a component that toggle a pop-up on or off, the popUpStatus bit of state might properly belong just to your component and would not need to go into the global Redux store. Redux modules are also a central part of the Grove architecture, so if you are planning to make your extension reusable, that would be a point in favor of using Redux for application-wide state. There are many articles out there on this, here is one of them.

Default Node middle-tier

The Grove Node middle-tier is present in this repository as a git submodule. You can learn more about this Grove middle-tier Application in its repository.

MarkLogic Configuration

We recommend using ml-gradle to bootstrap and configure your MarkLogic databases, security, and app servers. This Template provides a standard configuration as a git submodule in the marklogic directory.

You should become familiar with all the MarkLogic automation goodness that ml-gradle provides, starting with the project's README.

You may need to update, for example, the host, port, or administrative user for your MarkLogic REST server. ml-gradle makes that easy.

Under the covers, ml-gradle uses the MarkLogic Content Pump (mlcp) to load data into MarkLogic. MarkLogic provides an excellent guide to using mlcp, and the ml-gradle Wiki describes how to integrate mlcp with ml-gradle.

Contributing

We welcome contributions! A big motivation behind this project is to improve code quality through code reuse. Please read our Best Practices document to better understand the practices and philosophies that we hope will keep this project cohesive.