Skip to content

Instantly share code, notes, and snippets.

@gwenshap
Created October 22, 2023 03:45
Show Gist options
  • Save gwenshap/916e524408778f546ec35abfe7877995 to your computer and use it in GitHub Desktop.
Save gwenshap/916e524408778f546ec35abfe7877995 to your computer and use it in GitHub Desktop.
Script for Getting Started in Java Tutorial

Getting Started with Nile - Java

Hey everyone, I'm Gwen from Nile. Nile is a Serverless Postgres for building modern SaaS. SaaS applications are multi-tenant, and Nile provides tenant virtualization - the ability to create and access tenant databases anywhere in the world, but with the simplicity of a single DB.

In this tutorial, I'll show how I build a simple SaaS using Nile together with Spring Boot. You'll see how tenant virtualization makes it simpler. I'm going to start by showing you how to setup and run the example application. Then I'll go over the example and explain the code behind it, so you'll learn how to use Nile in your applications too. Lets do it!

First things first, lets sign in to Nile and create a database. We'll use the default name. And because Nile is serverless Postgres, it takes just one click to create a database.

Now note that the database already has a [00:01:00] tenants table. This is what we call built in tables. And because tenants are such an important concept to every SaaS and to Nile, we're providing a table with some columns that you'll probably need - like name!

Nile has few more of these built-in tables. If you go to our docs, you can learn all about those.

Built in tables are nice, but in order to build my application, I need to create my own table too.

So, let me create a table for storing all the todo lists for all my tenants. Do you see the tenant ID column in the table? Meaning that each row belongs to a specific tenant? We call these tables tenant aware. Tables without tenant_id column are "shared tables".

OK, we are done setting up the database. One last step here is to grab the database credentials. We'll need them when we configure our [00:02:00] application.

Next we'll switch to our trusted terminal and start by cloning the example. We'll go into the example directory, open the configuration file, and enter the database credentials that we grabbed earlier.

now all we need to do is build the example

and run it

Since this is a backend application, I'm using curl to interact with it. So I can call this route to create a tenant, and then call this other route to create a todo task. If I want to list tasks for a specific tenant, I can call this route. You may be wondering "what's the big deal? we've all built simple services like this". Well, let me show you how this last endpoint works and you'll see.

First, when we are setting up the Spring application, you can see that we are specifying a custom data source and an interceptor.

The inteceptor runs before [00:03:00] the handlers, picks the tenant ID from the path, and saves it to a threadlocal variable.

Next we run the handler. This is the cool part. As you can see, we are calling JPA's built-in "findAll". We are not applying any filters here. But this doesn't return all tasks. Why? Because of the tenant-aware data source.

The tenant aware data source makes sure that every time we pick up a connection from the pool, before running any queries, it will tell Nile to set the tenant config for this session.

Setting the tenant context is like getting a connection to a virtual database that is dedicated to that tenant. So everything you do with this connection - select, updates, deletes, will only have access to data for that tenant. It gives you both the safety that you won't accidentally leak data between customers, and it makes the controller code simpler. The [00:04:00] more controllers you have, the more valuable this becomes.

One way to see this impact is by looking at the "insecure route" - you can see that it has the exact same code. But because this route isn't intercepted, if I now call this endpoint, you'll see that this "leaks" all the tasks for all tenants. Not good! Don't do this. Definitely not in production.

OK, so thats enough tutorial for today. You've learned about Nile's built-in tables, tenant aware table, and how Nile uses session contexts to provide tenant virtualization. And you've learned how to use all these concepts to build a simple yet secure SaaS with Nile and Sprint Boot.

I hope you followed along with the example code on github, but if you haven't, I encourage you to try now. If you have any questions, if you want to discuss or argue. Please join our community discord or [00:05:00] open a discussion on our GitHub. Thank you so much and I hope you're going to build a very successful SaaS with Nile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment