React + MOBX + YAWP!

One common stack that I’ve been using to build apps is the React + MOBX + YAWP! combo.

Why?

In this simple tutorial I’ll show you how to create a reactive API to automatically save products to the server as you type.

The source code of this tutorial can be found here

Setup

Node, npm and create-react-app

npm install create-react-app

Create the project folder structure

mkdir reactive-yawp
cd reactive-yawp

Create the ReactJS project

create-react-app react-yawp
mv react-yawp web
cd web
npm install yawp --save
npm install mobx --save
npm install mobx-react --save

Create the yawp backend

mvn archetype:generate \
    -DarchetypeGroupId=io.yawp \
    -DarchetypeArtifactId=yawp \
    -DarchetypeVersion=LATEST \
    -DgroupId=demo \
    -DartifactId=demo \
    -Dversion=1.0-SNAPSHOT

mv demo api

A simple backend

For this tutorial we will have a very simple API containing a /produts resource endpoint:

cd api
mvn yawp:endpoint -Dmodel=product

Open the created Product.java file and add the name attribute:

@Endpoint(path = "/products")
public class Product {

    @Id
    IdRef<Product> id;

    String name;

}

A simple reactive app

Now it is time to create the app logic.

First we create the yawp Product client. Inside the folder web add the following content to the file Product.js:

import yawp from 'yawp';
import {extendObservable, observe} from 'mobx';

yawp.config(c => {
    // do this only for dev
    c.baseUrl('http://localhost:8080/api');
});

class Product extends yawp('/products') {

    constructor(attrs) {
        super();
        extendObservable(this, attrs);
        observe(this, () => this.save());
    }

}

export default Product;

Now we create a form to edit products. Change the content of the file App.js to be:

import React, {Component} from 'react';
import {observer} from 'mobx-react';
import Product from './Product';

class App extends Component {

    product = new Product({name: ''});

    onChange = (event) => {
        this.product.name = event.target.value;
    };

    render() {
        return (
            <div>
                <form>
                    <input type="text"
                           placeholder="name"
                           value={this.product.name}
                           onChange={this.onChange}/>
                </form>
            </div>
        );
    }
}

export default observer(App);

Running the demo

Now that everything is done, lets run and check it out.

In one terminal, run the yawp devserver:

cd api
mvn yawp:devserver

In other terminal, run the react devserver:

cd web
npm start

Your default browser should open the address http://localhost:3000. Just open the network monitor to check the server requests and then start typing at the name input. Just notice that everytime you type a letter the product will be automatically persisted to the server.

Conclusion

As you can see, this is a very simple setup. But it can be extended to construct more complex reactive apps that easily interact with your yawp backend in a very organized way.