Create a CRUD App With React, Kotlin, and Spring Boot
Create a CRUD App With React, Kotlin, and Spring Boot
This in-depth tutorial will go over how to create a secure CRUD application using a combination of ReactJS, Kotlin, Spring Boot, and OpenID.
Join the DZone community and get the full member experience.Join For Free
Buckle up—we’re going to use a lot of tools in this tutorial. We don’t have enough time to dive too deeply into any of them, so it will be helpful if you are familiar with React, Kotlin, Spring Boot, and REST APIs before we get started.
Our goal today is to use React for the frontend and Kotlin with Spring Boot for the backend to build a client and server application. First, you’ll build the app unsecured, and then you’ll use Okta to secure it. You’ll secure the frontend with OAuth 2.0 login, and you’ll secure the backend with a JSON Web Token and Spring Boot’s resource server OAuth implementation.
You’ll need to install a few things before you get started.
Java 11: If you don’t have Java 11, you can install OpenJDK. The OpenJDK website has instructions for installation. OpenJDK can also be installed using Homebrew. SDKMAN is another excellent option for installing and managing Java versions.
Node 12: You’ll need Node to create and run your React application. You can install it with Homebrew or download it from nodejs.org.
HTTPie: This is a simple command-line utility for making HTTP requests. You’ll use this to test the REST application. Check out the installation instructions on their website.
Okta Developer Account: You’ll be using Okta as an OAuth/OIDC provider to add JWT authentication and authorization to the application. Go to developer.okta.com/signup and sign up for a free developer account, if you haven’t already.
To get the party started, you’re going to use the Spring Initializr. It’s a great resource that makes getting started with Spring Boot projects super simple. If you want to dig into the options, take a look at the Spring Initializr GitHub page.
Open this link to a pre-configured project for this tutorial.
Take a moment to peruse the pre-selected options. Note a feature that I really like: you can explore the project online using the Explore button at the bottom of the page.
To highlight some of the important settings:
- Project: Gradle project (vs. Maven, because XML. Ugh. Holy 1999!)
- Language: Kotlin
com.okta.kotlin(this defines the package of the app files)
resourceserver(determines the project identifier as well as the name of the generated artifact)
- Spring Web (Spring Boot’s basic web capabilities)
- Spring Data JPA (Spring Boot’s data model Java persistence)
- Rest Repositories (Spring Boot’s ability to turn JPA repositories directly into REST APIs)
- H2 Database (In-memory SQL database for data model persistence)
Once you’re ready, click the green Generate button at the bottom of the Spring Initializr page. Download the project and move it to a suitable parent directory before unzipping it. You’re also going to create a React frontend, so you might want to make a
kotlin-react-app parent directory for both projects.
You can test the starter project by opening a shell and running the following command from the resource server project’s base directory.
Give that a few seconds to run. You should see something like this:
Open a separate shell and use HTTPie to make a simple request.
You may be wondering why, without even defining a controller, you have any response at all. This is because by including the
spring-boot-starter-data-rest starter dependency, you have included Spring’s auto-magic “hypermedia-based RESTful front end” (as Spring describes it in their docs).
A “hypermedia-based RESTful front end” is a REST API that uses Hypertext Application Language (HAL) format to output descriptive JSON. It’s essentially a systematic way for a REST API to describe itself to client applications and for the client applications to easily navigate between the various endpoints.
/profile endpoint that you see is an endpoint automatically added by the
spring-boot-starter-data-rest starter dependency.
Otherwise, there isn’t much going on yet. That’s about to change!
The next step is to create a REST API using Kotlin and Spring Boot. For this example application, you’re going to model a list of coffee shops (‘cause I spend a lot of time in coffee shops, and not all coffee shops are created equal).
One of the nice things about Spring Boot is that if you define a data model and a repository, it can automatically expose that data as a REST API using the aforementioned HAL. In practice, in production, you may find yourself needing to create custom controllers for your REST APIs, since you may need to inject business logic between the data and the client apps. However, this auto-generated REST API is a great start and may be enough for simple applications.
So, step 1. Define the data model.
Create a new Kotlin class called
CoffeeShopModel.kt in the
Step 2. Define the repository. Create a Kotlin class called
CoffeeShopRepository.kt in the same package.
That’s all you have to do to turn a data model into a REST API with full CRUD (Create, Read, Update, and Delete) capabilities. The magic happens primarily with two technologies: Spring Data JPA and the Spring Data
@RepositoryRestResource annotation. Spring Data JPA is what turns the data model into a persisted entity, using our H2 database. In our case, the database is in-memory by default, so nothing will be persisted across database restarts. Obviously, in a production app, you’d need to connect the app to an actual SQL database instance.
@RepositoryRestResource and the
CrudRepository are what take the persisted model and turn it into a REST API. You can inspect the
CrudRepository to see what methods it exposes to get an idea of its capabilities (see its API docs).
Before you test the REST API, you need to make a change to the
ResourceServerApplication class. This is not a functional change. It adds a couple of sample coffees shop to your in-memory database so that you have something to work with.
Restart everything and test your new REST API.
Before you move on to the React UI, make two more changes to the REST API. You’ll notice above that the
id field is not being returned as part of the JSON. This is inconvenient. Also, it’d be better if the REST API was set to have a base context path of
/api, making the full path
To make these changes, you need to add a
RepositoryRestConfigurer configuration class.
If you re-start the resource server and execute an
http :8080/api/coffeeshops request, you’ll find that the
id field is now included in the JSON response.
You will use Create React App to create the starter React application. The project is well documented on the Create React App homepage. It does a lot of routine work for us, setting up a React application.
From the root directory of the project (the parent directory of the Spring Boot resource server project), run the following command:
If that doesn’t work, as it didn’t for me, failing with a 404 error, you can use
npx instead (requires that Node be installed):
Once the client application is created, navigate into the
client directory and add a few dependencies:
This installs Bootstrap, React Router, and Reactstrap. It’s unlikely I have to tell you what Bootstrap is, but if you want to dig deeper, take a look at the project page.
react-router-dom provides DOM bindings for React Router (their docs). Reactstrap is a library of React components that leverage Bootstrap to provide a set of mobile-friendly UI components (their docs).
Add Bootstrap’s CSS file as an import in
Instead of using config values to set the resource server’s URL, you can use a proxy. Do this by adding the following to the
Take a look at the Create React App docs on this feature to learn more about proxying requests in development.
Run the React app using
yarn start (ensure your Spring Boot resource server is running). You should see a very simple list of the coffee shop names and addresses.
The UI as it is doesn’t do very much except demonstrate successful communication between the client and the server. The next step is to add some components, such as a navigation bar, a page for editing and adding coffee shops, and a nicer way to display the data. You’re also going to use routing to map URLs to app pages.
src/App.js to match the following. This adds three routes: a home route, a coffee shop list route, and a route for editing and creating new coffee shop entries. You’ll notice that the module uses composition (via the
render() method) to pass the
Api class and the
NavBar module to the route components. In our current app state, without authentication and authorization, this is unnecessary. However, once you add in OAuth, you’ll see how this allows you to keep all of the auth logic in one place, avoiding a bunch of repeated code (or having to use something like MobX or Redux to manage a global state).
src/Home.js, with the following contents. This will be a simple home page. All it does is display the navigation bar and a button to open the list of coffee shops.
src/NavBar.js. The navbar displays a “Home” link, as well as a link to Okta’s Twitter channel and a link to the project repository.
The next file holds the components that display the coffee shops in a responsive, card-style grid layout. Create a new file,
src/CoffeeShopsList.js, and add the following contents. There are two components in this file.
CoffeeShop is a simple, functional component that encapsulates the display of each coffee shop item.
CoffeeShopsList manages the overall display logic as well as the asynchronous calls to the server for loading and updating data.
The next new file,
src/CoffeeShopEdit.js, is the component that is responsible for editing existing coffee shop entries and creating new ones. It demonstrates the use of Reactstrap form elements, as well as making some asynchronous calls to the server.
Create one more new file,
src/Api.js. This module serves to centralize all of the server request logic. It is written so that it allows you to pass an authorization token to its constructor (which you’ll get to in the next section), and it will set the appropriate header. Without an auth token, it makes an unauthenticated request.
Finally, add some styling to make things look good. Modify
src/App.css to have the CSS below.
yarn start again if you need to (you may not need to; if you left it running, it should update automatically as you make changes). Make sure your resource server is running as well.
Take a look at the updated app at
You’ll see the new home page with the navbar.
Press the Manage Coffee Shops button.
You can now view, edit, create, and delete coffee shops.
You’ve got a nice, functional client and server application going. Don’t rest on your laurels yet! It’s unsecured, and if you leave that thing unattended, hackers will have it spewing spam and twist it into cheating little old ladies out of their retirement funds quicker than you can figure out what the heck a ‘hook’ is.
The next step is to secure it. You’re going to implement OAuth 2.0 login on the frontend. On the back end, you’re going to use a JSON Web Token (JWT) to secure the resource server. To make life much easier, you’re going to use Okta as your OAuth provider. Using Okta means you won’t have to write or maintain any login code or handle user passwords; nor will you have to waste any time mucking around writing code to verify tokens.
Before you make any code changes, though, you need to log into your Okta developer account and create an OpenID Connect (OIDC) application.
OpenID Connect (or, OIDC) is an authentication protocol built on top of OAuth 2.0, which is an authorization protocol. Very briefly, OIDC allows you to know who a client is, and OAuth 2.0 allows you to determine what they’re allowed to do. Together they specify a complete authentication and authorization system. You’re going to use Okta’s implementation of these protocols as your OAuth 2.0 / OIDC provider.
To do this, you need to create an OIDC application in your Okta account. This configures and activates the OIDC application that your frontend application and backend resources server will interact with when verifying authentication and authorization.
If you haven’t already, head over to developer.okta.com to sign up for a free account. Once you have an account, open the developer dashboard and create an OpenID Connect (OIDC) application by clicking on the Applications top-menu item, and then on the Add Application button.
- Select Single-Page App and click Next
- Change the name to be “Kotlin React App”
- Change the Base URI to
- Change the Login redirect URIs to have
- Update the Logout redirect URIs to have
You’ll need your Client ID in a moment.
Securing the Spring Boot REST API is super easy. First, you need to add the Okta Spring Boot Starter to your Gradle project. This is a library we’ve created that streamlines adding OAuth 2.0/OIDC to your Spring Boot app with Okta.
Add the dependency in
Next, create a
SecurityConfiguration class to configure Spring Boot as an OAuth 2.0 resource server.
NOTE: This file also does a couple of other things: 1) it disables CSRF (Cross-site forgery protection), and 2) it configures the resource server to send a 401 instead of a blank page if a request is not authorized. Disabling CSRF in production is definitely NOT recommended, and you’re doing it here to simplify things so you can focus on OAuth 2.0 login and JWT authentication. To see how to implement CSRF protection, take a look at some of the other blog posts at the end of this tutorial.
Finally, add some configuration to
src/main/resources/application.properties. Here you need the Okta Issuer URL (from the Okta developer dashboard, go to API > Authorization Servers and look in the table under the default server). You also need the Client ID from the OIDC application you just created.
That’s it. The resource server now requires a valid JWT for all requests.
Stop and restart the resource server:
You can test that it requires a JWT by opening a shell and running a simple request using HTTPie:
You’ll get a 401 / Unauthorized:
The first step to adding Okta OAuth 2.0 login to your frontend React application is to add the Okta React SDK. Take a look at the project’s GitHub page for more info.
Use Yarn to add the project dependency to your React client.
src/App.js to match the following. Fill in your Client ID and your Issuer URL in the Security component properties.
Security component is where the Okta OAuth configuration happens. You need to fill in your
clientId and your
issuer in the properties there.
You’ll also notice that I chose to centralize all the security logic in a wrapper component called
AuthWrapper. This allows you to handle all authentication-related logic in one place and pass down the authentication state as properties. It also allows you to pass down the
Api module with the access token to the child components. This keeps a lot of the security logic out of the route/view components and avoids some repeated code, which I like.
withAuth() function supplied by the Okta React SDK can be applied to any React component (that is a child of the
Security component). Thus, it’s also possible not to use a wrapper class like this and inject the
auth prop into the various routes directly. Ultimately, in an app in production, the auth state would likely be moved to a global state using something like MobX or Redux.
Two more files need to be updated, the home page and the navigation bar.
src/NavBar.js to add login and logout buttons:
Time to test the secured app.
Run the resource server (if you need to):
Start the React client:
Open a browser:
Click the Login button in the header. You’ll be redirected to the Okta login page. Log in using your Okta credentials.
When you return to your client app’s homepage, click the Manage Coffee Shops button.
From this page, you can edit, delete, and add new coffee shops.
All done! In this tutorial, you created a web-based application using a React frontend with data being served by a Kotlin Spring Boot resource server. You also saw how to use a free developer account from Okta to add OAuth 2.0 login to your application and to secure your resource server.
You can find the source code for this example on GitHub in the okta-kotlin-react-crud-example repository.
If you want to keep learning, take a look at these related posts:
- Kotlin: A Beginner’s Guide and Tutorial
- Use React and Spring Boot to Build a Simple CRUD App
- ^^ Shows how to configure CSRF protection with Spring Boot and React
- Build a Basic CRUD App in Android with Kotlin
- Build a Web App with Spring Boot and Spring Security in 15 Minutes
- Create a Secure Spring REST API
- Build a Simple CRUD App with Spring Boot and Vue.js
Published at DZone with permission of Andrew Hughes , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.