Today we’ll build a simple Spring Boot Application and integrate it with DynamoDB.
We’ll configure our Spring Boot application to use a local DynamoDB instance using Spring Data. We’ll create an example data model and repository class as well as perform actual database operations using an integration test. Notice that in similar way you can work with Amazon DynamoDB.
What is DynamoDB
Amazon DynamoDB is a fast and flexible NoSQL database service for all applications that need consistent, single-digit millisecond latency at any scale. It is a fully managed cloud database and supports both document and key-value store models. Its flexible data model, reliable performance, and automatic scaling of throughput capacity make it a great fit for mobile, web, gaming, ad tech, IoT, and many other applications. DynamoDB is very similar to such NoSQL databases as Cassandra or MongoDB. DynamoDB offers fast, consistent and predictable performance and is massively scalable.
Let’s now install a local instance of DynamoDB for learning purposes and to avoid incurring the cost of running a live instance on Amazon.
Running DynamoDB locally makes more sense than running on AWS in development mode, because the local instance will be running as an executable JAR file.
You can find instructions on how to run DynamoDB locally here.
Maven Dependencies
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-releasetrain</artifactId> <version>Hopper-SR10</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-dynamodb</artifactId> <version>1.11.34</version> </dependency> <dependency> <groupId>com.github.derjust</groupId> <artifactId>spring-data-dynamodb</artifactId> <version>4.3.1</version> </dependency> </dependencies>
Application Configuration
Put the following configurations in the application.properties
file:
amazon.dynamodb.endpoint=http://localhost:8000/ amazon.aws.accesskey=key amazon.aws.secretkey=key2
The secret keys listed above are just arbitrary values for your local config. When accessing a local instance of DynamoDB these fields need to be populated by some values but are not needed to actually authenticate.
Spring will automatically load the properties from application.properties
file:
@Configuration @EnableDynamoDBRepositories(basePackages = "com.codeflex.spring.dynamodb.example") public class DynamoDBConfig { @Value("${amazon.dynamodb.endpoint}") private String amazonDynamoDBEndpoint; @Value("${amazon.aws.accesskey}") private String amazonAWSAccessKey; @Value("${amazon.aws.secretkey}") private String amazonAWSSecretKey; @Bean public AmazonDynamoDB amazonDynamoDB() { AmazonDynamoDB dynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials()); if (!StringUtils.isEmpty(amazonDynamoDBEndpoint)) { dynamoDB.setEndpoint(amazonDynamoDBEndpoint); } return dynamoDB; } @Bean public AWSCredentials amazonAWSCredentials() { return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey); } }
Data Model
Let’s create a simple Book
class that will be stored in our DynamoDB. We’ll use annotations in a similar way just like you probably already used once for Hibernate projects.
@DynamoDBTable(tableName = "Book") public class Book { private String id; private String name; private String price; @DynamoDBHashKey @DynamoDBAutoGeneratedKey public String getId() { return id; } @DynamoDBAttribute public String getName() { return name; } @DynamoDBAttribute public String getPrice() { return price; } }
Book Repository Class
Now, let’s create BookRepository interface to define the CRUD
functionality. All repositories used to read and persist data from DynamoDB will implement this interface:
@EnableScan public interface BookRepository extends CrudRepository<Book, String> { List<Book> findById(String id); }
Testing our Spring Boot Application with DynamoDB
Now, we want to test our application to ensure that we can connect and perform operations on our local DynamoDB:
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = Application.class) @WebAppConfiguration @ActiveProfiles("local") @TestPropertySource(properties = { "amazon.dynamodb.endpoint=http://localhost:8000/", "amazon.aws.accesskey=yourAccessKey", "amazon.aws.secretkey=yourSecretKey" }) public class BookRepositoryIntegrationTest { private DynamoDBMapper dynamoDBMapper; @Autowired private AmazonDynamoDB amazonDynamoDB; @Autowired BookRepository repository; private static final String ID = "1"; private static final String NAME = "Learn Java & DevOps on Codeflex.co"; private static final String PRICE = "100"; @Before public void setup() throws Exception { dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB); CreateTableRequest tableRequest = dynamoDBMapper.generateCreateTableRequest(Book.class); tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L)); amazonDynamoDB.createTable(tableRequest); // your code here... dynamoDBMapper.batchDelete((List<Book>)repository.findAll()); } @Test public void dynamoDBTestCase() { Book codeflex = new Book(ID, NAME, PRICE); BookRepository.save(codeflex); List<Book> theBook = (List<Book>) repository.findAll(); assertTrue("Book found.", theBook.size() > 0); assertTrue("The book name is correct.", theBook.get(0).getName().equals(NAME)); } }
This is it! You have now your Spring Boot Application communicating with DynamoDB.