Building Microservices with Spring and Cloud Spanner

Develop and test your Spring applications and Google Cloud Spanner

Image by GCP Podcast

Why choosing Spanner?

Image by Author

Spanner Emulator

$ docker pull gcr.io/cloud-spanner-emulator/emulator
$ docker run -d --name spanner-emulator -p 9010:9010 -p 9020:9020 gcr.io/cloud-spanner-emulator/emulator

Instances and Databases in Spanner

$ gcloud config configurations create emulator
$ gcloud config set auth/disable_credentials true
$ gcloud config set project your-project-id
$ gcloud config set api_endpoint_overrides/spanner http://localhost:9020/
$ gcloud spanner instances create test-instance \
--description="Test Instance" --config=emulator-config --nodes=1
$ gcloud spanner databases create test-database \
--instance test-instance
$ gcloud spanner databases list --instance test-instance

Setting up the application

implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("com.google.cloud:google-cloud-spanner:$spannerVersion")
implementation("com.google.cloud:google-cloud-spanner-jdbc:$spannerJdbcVersion")
implementation("com.google.cloud:google-cloud-spanner-hibernate-dialect:$hibernateDialectVersion")
implementation("com.google.cloudspannerecosystem:liquibase-spanner:$liquibaseVersion")
databaseChangeLog:
- preConditions:
onFail: HALT
onError: HALT

- changeSet:
id: create-singers-table
author: spanner-examples
changes:
- createTable:
tableName: singer
columns:
- column:
name: singer_id
type: STRING(36)
constraints:
primaryKey: true
- column:
name: singer_name
type: STRING(255)
constraints:
nullable: false
your-project-id=test-spanner
your-instance=test-instance
your-database=test-database

# spanner datasource
spring.datasource.driver-class-name=com.google.cloud.spanner.jdbc.JdbcDriver
spring.jpa.properties.hibernate.dialect=com.google.cloud.spanner.hibernate.SpannerDialect
spring.datasource.url=jdbc:cloudspanner:/\
projects/${your-project-id}/\
instances/${your-instance}/\
databases/${your-database}?\
autoConfigEmulator=true
@Entity
@Table(name = "singer")
class Singer(
@Id @GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "singer_id") val id: String?,
@Column(name = "singer_name") val name: String = ""
)

interface SingerRepo : JpaRepository<Singer, String>

Testing the Application

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.testcontainers:testcontainers:$testcontainersVersion")
testImplementation("org.testcontainers:gcloud:$testcontainersVersion")
testImplementation("org.testcontainers:junit-jupiter:$testcontainersVersion")

Summary

--

--

Software Engineer. Instructor. Trying to learn something new every day. Trying to teach what I wish I knew earlier.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Jonathan Manera

Software Engineer. Instructor. Trying to learn something new every day. Trying to teach what I wish I knew earlier.