0% found this document useful (0 votes)
53 views9 pages

House Dzone Refcard 379 Getting Started Serverless

This document provides instructions for building a sample serverless application using a Java backend with Quarkus and a Node.js/React frontend. It begins by building out the backend REST API with Quarkus to enable CRUD operations on a CockroachDB serverless database. It then builds the frontend with Node.js and React to display and add items to the leaderboard database. Finally, it deploys the full application to Heroku.

Uploaded by

Fernando
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
53 views9 pages

House Dzone Refcard 379 Getting Started Serverless

This document provides instructions for building a sample serverless application using a Java backend with Quarkus and a Node.js/React frontend. It begins by building out the backend REST API with Quarkus to enable CRUD operations on a CockroachDB serverless database. It then builds the frontend with Node.js and React to display and add items to the leaderboard database. Finally, it deploys the full application to Heroku.

Uploaded by

Fernando
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

379

CONTENTS

Getting Started With •  When to Build With a Serverless


Database

Serverless Application
•  Building a Sample Serverless
Application
−  Build Out the App's Back End
−  Add the Serverless Database

Architecture −  Build Out the App's Front End


−  Add Items
−  Deploy to Heroku
•  Conclusion
RAIN LEANDER
DEVELOPER ADVOCATE, COCKROACH LABS

Before getting your hands in the soil, it's important to review what BUILDING A SAMPLE SERVERLESS
"serverless" actually means. Of course, servers are still present in APPLICATION
serverless computing; in a serverless architecture, DevOps teams In this tutorial, we'll demonstrate how to build a serverless Java
don't have to worry about building out, configuring, and managing application by creating the leaderboard app shown below:
the hardware. And for developers, serverless means that they can
Figure 1
communicate with the database as if it was a single API endpoint
in a cloud environment. All of which is to say: "Serverless" removes
application architecture maintenance, which creates more room for
innovation.

The intention of this Refcard is to help you easily get started with
serverless application architecture by jumping right into a hands-on
tutorial for building a serverless Java web application.

WHEN TO BUILD WITH A SERVERLESS


DATABASE
Almost all modern cloud-native applications require persistent
data storage. However, storing data becomes more challenging in
serverless architectures where each service is deployed independently.
Specifically, transactions in serverless apps require consistency so
that they can eventually be reconciled, but the applications also need
to scale effectively without being hampered by fragmented data.
For these reasons, it's important to use a serverless database
because it will allow for rapid development of scalable data stores for
modern applications.

For the following tutorial, we're going to use CockroachDB Serverless,


but there are a handful of other serverless databases available, such
as Fauna DB and Amazon Aurora Serverless. CockroachDB is easy to
use with Quarkus and offers support for Hibernate ORM, and Quarkus
works particularly well with Hibernate, thanks to Panache. To
implement a serverless solution, you only need to create the cluster
and connect your application to the database, similar to how you would
add any other SQL database. This means you can start building your
application in minutes.

REFCARD | JUNE 2022 1


REFCARD | GETTING STARTED WITH SERVERLESS APPLICATION ARCHITECTURE

We'll first build the app's back end using Quarkus to enable CRUD Figure 2
operations on CockroachDB Serverless, which we will then use to store
leaderboard items displayed on the front end. We'll build the front
end using Node.js and React, enabling users to display and add new
leaderboard items. Then, we will deploy the entire solution to Heroku
to make it globally available.

You can follow along using the companion repository on GitHub.


Examples were created in Visual Studio Code on macOS, but we've
included instructions for other operating systems where necessary.

Note: We're assuming you have at least an intermediate level of Java


programming skills and are familiar with Quarkus. If you're unfamiliar
with JPA and MVC in Java, please check the following tutorial: "Learn
JPA & Hibernate."

Here is a list of tools you will need:

•  Visual Studio Code with the Extension Pack for Java


−  Check out Managing Extensions to learn how to install
the extension.

•  Java version 16.0.2, 2021-07-20

•  curl for app testing (you can use another testing tool if
you prefer)
Download the zip file to receive the Java project with a static page,
•  Node.js, since we will be using npm to build out React front end
an index.html file (in src/main/resources), one REST API, a
•  Git for version control GreetingResource.java file (in src/main/java/org/db), some

•  Maven, the build tool unit tests, and some Docker files.

•  A free Heroku account The GreetingResource.java file implements a simple /hello


endpoint with one GET method, which returns the static string,
BUILD OUT THE APP'S BACK END
Hello RESTEasy:
We'll start by creating the Quarkus back end. Let's go to the Quarkus
project generator and set up our application's extensions, which we @Path("/hello")

can think of as dependencies. public class GreetingResource {

In the Group field, enter "org.db." In the Artifact field, enter @GET
"cockroach-serverless." In the Build Tool field, enter "Maven." Next, @Produces(MediaType.TEXT_PLAIN)

select the following four packages: public String hello() {


return "Hello RESTEasy";
•  RESTEasy Classic }

•  RESTEasy Classic JSON-B }

•  REST resources for Hibernate ORM with Panache [quarkus-


To see this code at work, navigate to the unzipped file, /path/to/
hibernate-orm-rest-data-panache]
cockroach-serverless/ , and enter the following command in
•  JDBC Driver – PostgreSQL [quarkus-jdbc-postgresql] your terminal:

Once the project is configured, select Generate your application. ./mvnw quarkus:dev
Quarkus then displays another window where you can download the
source code (Figure 2). Next, use your browser and navigate to localhost:8080. You will see
index.html being rendered. You can ignore any test output generated
SEE FIGURE 2 IN NEXT COLUMN
in the log.

REFCARD | JUNE 2022 2


REFCARD | GETTING STARTED WITH SERVERLESS APPLICATION ARCHITECTURE

Figure 3 PanacheEntityResource, used as a base class, is generic and


implements our CRUD operations. It will work for instances of
LeaderboardItem and identify particular database objects using the
default identifier, Long (from the PanacheEntity class). Also note
that LeaderboardResource will automatically generate the REST
API endpoint exposed at the /leaderboard path.

We are now ready to create the CockroachDB database and connect it


to our back end.

ADD THE SERVERLESS DATABASE


If you do not have a free CockroachDB account, you will need to
create one. After signing up, you will be redirected to the dashboard.

Append the request to the /hello endpoint to see the static Select Create Cluster, and in the display that pops up, choose

string, Hello RESTEasy. Once this is done, we can add the class
Serverless. The Serverless option requires you to choose your cloud

implementing the actual REST API for our leaderboard app. Create a provider and its region: Set AWS as your provider and use the region

file called LeaderboardItem.java in src/main/java/org/db and closest to your physical location. Optionally, you can modify the

add the following code: cluster name, though we are using the default value, fluffy-possum.

package org.db; Select Create your free cluster to begin the process of creating
import javax.enterprise.inject.Produces; the cluster. In a few seconds, you will see a window containing your
import javax.persistence.Column; connection info:
import javax.persistence.Entity;
Figure 4
import io.quarkus.hibernate.orm.panache.
PanacheEntity;

@Entity
public class LeaderboardItem extends PanacheEntity {
@Column
public String name;
@Column
public double points;
}

This will represent the items on the leaderboard.

The LeaderboardItem class has two fields: name and points. The
class derives from PanacheEntity, so the getters and setters for
name and points fields will be generated automatically. Additionally,
PanacheEntity provides a default identifier, id, which helps to keep
the definition of the LeaderboardItem class clean and simple.

Next, let's implement the actual REST resource for the leaderboard
items. Add the LeaderboardResource.java class in the src/main/
java/org/db directory:

package org.db;

import io.quarkus.hibernate.orm.rest.data.panache.
Be sure to note your database password at this point, as this is the
PanacheEntityResource;
only place where you can reveal it. Otherwise, you'll need to reset the
public interface LeaderboardResource extends password using the CockroachDB dashboard, found in: SQL Users >
PanacheEntityResource Action > Change Password. While you have this window open, you
<LeaderboardItem, Long> {
will also want to grab a few more values that you'll soon need to
}
configure the application.properties class.

REFCARD | JUNE 2022 3


REFCARD | GETTING STARTED WITH SERVERLESS APPLICATION ARCHITECTURE

Select the Parameters Only dropdown and note the values it presents The item was successfully added to the database. We can check this
(username, host, database, and port): by sending a GET request to http://localhost:8080/leaderboard,
either using curl or a web browser:
Figure 5

Figure 7

BUILD OUT THE APP'S FRONT END


With the back end ready, let's add the front end. Because we will build
using React, we'll need to make sure we also have Node.js. Install it now
if necessary.

First, open your terminal and go to the project's directory. Create a new
directory called webapp in /src/main. Then, create the React project
by entering the following command:

npx create-react-app src/main/webapp/

Next, open src/main/resources/application.properties and


enter the following code. Replace the username, password, host, port, Figure 8

and database with the values taken from CockroachDB Serverless. Use
the cluster name in the JDBC URL:

# configure your datasource


quarkus.datasource.db-kind = postgresql
quarkus.datasource.username = dev
quarkus.datasource.password = <your password>
quarkus.datasource.jdbc.url =
jdbc:postgresql://<your host>:26257/<cluster- Enter y to proceed. The React web application will be bootstrapped
name>.<your database>
in src/main/webapp. You can preview the app by changing your
quarkus.hibernate-orm.database.generation = update working directory to src/main/webapp and then entering the
following command:
We are now ready to test the application. Go ahead and run the app
npm start
again by entering the following command in your terminal:

./mvnw quarkus:dev You will see the following welcome screen:

Then, navigate to localhost:8080/leaderboard. The resource Figure 9


returns an empty collection. We can add one item using curl:

curl -i -X POST -H "Content-Type:application/json"


-d "{ \"name\" : \"Dave\", \"points\" : \"100\"}"
http://localhost:8080/leaderboard

The resource should respond with a 201 HTTP status code:

Figure 6

REFCARD | JUNE 2022 4


REFCARD | GETTING STARTED WITH SERVERLESS APPLICATION ARCHITECTURE

Let's now customize our web app and add the leaderboard. We will use This component, when given the list of leaderboard items, will render
the PatternFly package to create the table. them as the two-column table we want to display:

Install the PatternFly npm package by invoking the following command Figure 10
from the src/main/webapp directory:

npm install @patternfly/patternfly –save

Then, import patternfly.css in index.js:

import React from 'react';


import ReactDOM from 'react-dom';
import './index.css'; To that end, the Leaderboard component iterates over the items
import App from './App';
collection and displays each item as a table row.
import reportWebVitals from './reportWebVitals';
import '@patternfly/patternfly/patternfly.css'; Let's now use the Leaderboard component in App.js:

import React, {Component} from 'react';


Next, create a subdirectory named components in the webapp/src
import Leaderboard from './components/leaderboard';
directory. Then, in webapp/src/components, create a leaderboard.
jsx file and add the following code:
class App extends Component {
state = {
import React from 'react'
items: []
}
const Leaderboard = ({ items }) => {
return (
componentDidMount() {
<div>
fetch('http://localhost:8080/leaderboard')
<center><h1>Leaderboard</h1></center>
.then(res => res.json())
<table className="pf-c-table pf-m-
.then((data) => {
grid-md">
this.setState({ items: data.
<thead>
sort((a,b)=>{return a.points < b.points}) })
<tr role="row">
})
<th
.catch(console.log)
role="columnheader">Name</th>
}
<th
role="columnheader">Points</th>
render () {
</tr>
return (
</thead>
<Leaderboard items={this.state.items} />
{items.map((item) => (
);
<tbody role="rowgroup">
}
<tr role="row">
}
<td role="cell">{item.
name}</td>
export default App;
<td role="cell">{item.
points}</td>
</tr> The App component will send a GET request to our Leaderboard
</tbody> resource, which we've implemented using the Quarkus REST API. The
))} collection of items retrieved from the API is stored in state.items and
</table> then passed to the Leaderboard React component. Importantly, the
</div>
items are also sorted in descending order by their points property.

) To make this work, we need to configure cross-origin resource sharing


}; (CORS). By default, the front end is exposed on the localhost at port
3000, while the REST API is exposed at port 8080. This could prevent
export default Leaderboard
fetching data from the API — the web browser could block a request due
to misconfigured CORS.

REFCARD | JUNE 2022 5


REFCARD | GETTING STARTED WITH SERVERLESS APPLICATION ARCHITECTURE

To enable CORS, add the following line to application.properties Next, implement the AddItem.jsx component with the code below:
in the Quarkus project:
import React from 'react';
quarkus.http.cors=true import './AddItem.css'

Now, run the REST API project again by running ./mvnw quarkus:dev class AddItem extends React.Component {
constructor(props) {
and restart the web application by running npm start. Then, open
super(props);
localhost:3000/leaderboard.
this.state = { name: '', points: 0 };
}
You should see something like this:

Figure 11 handleChange = (event) => {


this.setState({[event.target.name]: event.
target.value});

console.log(this.state);
}

handleSubmit = (event) => {


console.log(JSON.stringify(this.state));
fetch('http://localhost:8080/leaderboard', {
method: 'POST',
body: JSON.stringify(this.state),

At this point, we can add items using curl or any other REST API client. headers: {
'Content-Type': 'application/json'
Let's see how to do this.
},
ADD ITEMS }).then(function(response) {

We'll now add a form that enables users to add new entries to the return response.json();
});
leaderboard through REST API. The application will also contain two
links that enable the user to switch between the Leaderboard and
event.preventDefault();
Form screens:
}

Figure 12
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.
value}
name="name" onChange={this.
handleChange} placeholder="Name"/>
<br/>
<input type="text" value={this.state.
value}
name="points" onChange={this.
handleChange}placeholder="Points"/>
We start by supplementing the React app with the react router. To do
<br/>
so, install the react-router-dom npm package: <input type="submit" value="Submit" />
</form>
npm install react-router-dom
);
}
Then, in the components directory, add an AddItem.css file:
}

input {
export default AddItem
margin: 5px;
}
The AddItem component consists of a form with two text fields.

REFCARD | JUNE 2022 6


REFCARD | GETTING STARTED WITH SERVERLESS APPLICATION ARCHITECTURE

The values of these text fields are used to update the state of the Select Add item, then fill in the form:
component. When the user selects the Submit button, a POST request
Figure 13
is sent to our back end.

Finally, we modify App.js to include links to Leaderboard and


AddItem components:

import React, {Component} from 'react';


import {BrowserRouter as Router, Routes, Route,
Link} from 'react-router-dom'
import Leaderboard from './components/Leaderboard';
import AddItem from './components/AddItem';
After submitting the form, select Leaderboard and refresh the page to
class App extends Component { see the new item:
state = {
Figure 14
items: []
}

componentDidMount() {
fetch('http://localhost:8080/leaderboard')
.then(res => res.json())
.then((data) => {
this.setState({ items: data.
sort((a,b)=>{return a.points < b.points}) })
})
.catch(console.log)
}

render () {
You can also use the setInterval JavaScript function to automatically
return (
refresh the leaderboard at the predefined intervals.
<Router>
<div style={{padding: "5px"}}>
DEPLOY TO HEROKU
<Link to="/">Leaderboard</Link><br/>
In this section, we'll deploy our entire solution to Heroku, doing
<Link to="/addItem" >Add item</Link> <br/>
so in a cloud-native way by deploying the back end and front end
</div>
independently. To complete all of the instructions, you will need
<hr/> Heroku and Git accounts, as well as the Heroku CLI installed on your
development machine.
<Routes>
To install Heroku CLI on macOS, use brew:
<Route exact path='/'
element={<Leaderboard items={this.
brew install heroku/brew/heroku
state.items}/>} />
<Route exact path='/addItem'
On Ubuntu, use snap:
element={< AddItem />} />
</Routes> sudo snap install heroku --classic
</Router>
); On other Linux distributions, use a tarball.
}
} On Windows, use one of the dedicated installers.

BACK-END DEPLOYMENT
export default App;
First, let's deploy the back end through Heroku CLI and Git. Start by

Now, run the web app again. You can see the links at the top of the logging into Heroku:

Leaderboard window. heroku login

REFCARD | JUNE 2022 7


REFCARD | GETTING STARTED WITH SERVERLESS APPLICATION ARCHITECTURE

Then, update your application.properties file with the following Figure 16


configuration:

quarkus.http.port=${PORT:8080}

This updates the HTTP port on which our back end is listening for
requests so that it matches the port provided by Heroku. Next, create a
system.properties file:

echo "java.runtime.version=11" >> system.properties

We use this to set our JDK to version 11 to match the Quarkus


configuration. Next, create the Procfile, which Heroku uses to start
Append the /leaderboard path to the URL to see the back end
our application:
communicate with CockroachDB and return the list of leaderboard
echo "web: java \$JAVA_OPTS -jar target/quarkus-app/ items. Note that this list matches what we had before because the
quarkus-run.jar" >> Procfile data is retrieved from the same database:

Figure 17
Before we create our app, we need to collate everything through Git.
Initialize a local Git repository and commit all these files:

git init
git add .
FRONT-END DEPLOYMENT
git commit -am "Initial version"
After ensuring that the back end works, let's deploy the front end.
Now, create the application on Heroku: We will start by updating the code with the Heroku app's URL. In our
case, that is https://afternoon-fortress-35863.herokuapp.
heroku create
com/leaderboard. Your URL will be similar.

Finally, deploy through Git: Update this section of the App.js file — in src/main/webapp/src —

git push heroku main


with your URL:

componentDidMount() {
The output of this command should look similar to this: fetch('https://afternoon-fortress-35863.herokuapp.

Figure 15 com/leaderboard')
.then(res => res.json())
.then((data) => {
this.setState({ items: data.sort((a,b)=>{return
a.points < b.points}) })
})
.catch(console.log)
}

Then, update the URL in the AddItem.jsx file within src/main/


webapp/src/components:

handleSubmit = (event) => {


console.log(JSON.stringify(this.state));
fetch('https://afternoon-fortress-35863.herokuapp.
com/leaderboard', {
method: 'POST',
body: JSON.stringify(this.state),
headers: {
To see the app running, enter heroku open. This opens the default web 'Content-Type': 'application/json'
browser and navigates to the Heroku application URL (Figure 16). },
}).then(function(response) {
SEE FIGURE 16 IN NEXT COLUMN
CODE CONTINUES ON NEXT PAGE

REFCARD | JUNE 2022 8


REFCARD | GETTING STARTED WITH SERVERLESS APPLICATION ARCHITECTURE

return response.json(); The item appears as an entry in the leaderboard:


}); Figure 20

event.preventDefault();
}

Before proceeding, let's ensure everything works locally. Change your


working directory to src/main/webapp and then run using npm
start. Then, go to localhost:3000. Note that it may take longer than
before to retrieve leaderboard items. Now, we are ready to deploy the
front end to Heroku. Start by creating the Procfile:

echo "web: npm start" >> Procfile

Now, initialize another repository. Add and commit all of the files,
ensuring to do this from the src/main/webapp subdirectory:

git init
CONCLUSION
git add .
In this Refcard, we walked through the creation and deployment of a
git commit -am "webapp"
Java application, using Quarkus for the back end, React for the front
Create the new Heroku app: end, CockroachDB for our serverless database, Panache for ORM,
and Heroku to deploy the whole package. As you've seen, we quickly
heroku create
connected CockroachDB to our Quarkus back end, but we could have

Finally, deploy the front end through Git: just as easily deployed to Heroku as a Docker container instead. We
also demonstrated how easy it is to automatically generate REST CRUD
git push heroku main
resources using Panache. All of these tools accelerate the development
of serverless apps. And by removing server-centric friction from the
All that remains to do now is to open your application:
application development process, serverless development liberates
heroku open
developers to spend more time on innovation and feature development,
which will ultimately result in better end-user experiences.
You should see the solution up and running:

Figure 18

WRITTEN BY RAIN LEANDER,


DEVELOPER ADVOCATE, COCKROACH LABS

Rain Leander is a systematic, slightly psychic,


interdisciplinary community liaison with a
bachelor's in dance and a master's in IT. Rain is a
developer advocate at CockroachDB, an author of many application
development tutorial guides, and an active technical contributor
with Tinkerbell, OpenStack, RDO, TripleO, Fedora, and DjangoGirls.

600 Park Offices Drive, Suite 300


Research Triangle Park, NC 27709
888.678.0399 | 919.678.0300
Try to add another item:
At DZone, we foster a collaborative environment that empowers developers and
tech professionals to share knowledge, build skills, and solve problems through
Figure 19 content, code, and community. We thoughtfully — and with intention — challenge
the status quo and value diverse perspectives so that, as one, we can inspire
positive change through technology.

Copyright © 2022 DZone, Inc. All rights reserved. No part of this publication
may be reproduced, stored in a retrieval system, or transmitted, in any form or
by means of electronic, mechanical, photocopying, or otherwise, without prior
written permission of the publisher.

REFCARD | JUNE 2022 9

You might also like