Spring boot CRUD (Create, Read, Update, Delete) demo application with cassandra DB and API documentation using Swaager and OpenAPI UI
Spring boot CRUD (Create, Read, Update, Delete) demo application with cassandra DB - In this application, we have implemented CRUD (Create, Read, Update, Delete) operations using spring data and cassandra DB.
GOTO > ~/absolute-path-to-directory/spring-boot-cassandra-crud and try below command in terminal
mvn spring-boot:run
it will run application as spring boot application
or
mvn clean install
it will build application and create jar file under target directory
Run jar file from below path with given command
java -jar ~/path-to-spring-boot-cassandra-crud/target/spring-boot-cassandra-crud-0.0.1-SNAPSHOT.jar
Or
run main method from
SpringBootCassandraCrudApplication.java
as spring boot application.
Note : In SpringBootCassandraCrudApplication.java class we have autowired SuperHero repository. If there is no record present in DB for SuperHero model class, static data is getting inserted in DB from HelperUtil.java class when we are starting the app for the first time. |
Step 1: Download JDK8 from JDK site. Step 2: Install downloaded an executable file. Step 3: Add JDK8 path as environment variable.
Step 1: Python2.7 is mandatory for cqlsh to handle user requests. Download Python2.7 from Python site. Step 2: Install downloaded an executable file. Step 3: Add Python2.7 path as environment variable.
Step 1: Download the latest version of apache-cassandra-x.xx.x from Cassandra site. Step 2: Unzip the compressed zip file using a compression tool to any location. Ex. c:\apache-cassandra-x.xx.x Step 3: Add c:\apache-cassandra-x.xx.x\bin path as environment variable.
Make sure bin path is set for cassandra in environment variable.
cassandra
If no error on the console means cassandra is started and running.
Make sure path is set for the python in environment variable.
cqlsh
If no error on the console means cqlsh is connected.
Need to add below dependency to enable cassandra in pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
<!-- For Boilerplate code (Getters/Setters/Constructors) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
For API documentation using swagger and OpenApi UI add below dependency.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.4.4</version>
</dependency>
Placed properties in application.yml file related to cassandra which we are reading in CassandraConfig.java class and configuring cassandra connection for Cassandra. API documentation related swagger UI path is also placed here which will enable Swagger API Doc on same path. src/main/resources/application.yml
spring:
data:
cassandra:
contact-points: localhost
port: 9042
keyspace-name: simple_crud
#username: cassandra
#password: cassandra
#schema-act: create_if_not_exists
springdoc:
version: 1.0.0
swagger-ui:
path: /swagger-ui-custom.html
Below are the model classes which we will store in cassandra and perform CRUD operations. com.arya.cassandra.model.SuperHero.java com.arya.cassandra.model.SuperPowers.java
@Data
@Builder
@Table("super_hero")
public class SuperHero implements Serializable {
@PrimaryKey
private Long id;
private String name;
@Column("super_name")
private String superName;
private String profession;
private int age;
@Column("super_powers")
private SuperPowers superPowers;
}
@Data
@Builder
@UserDefinedType("super_powers")
public class SuperPowers implements Serializable {
private String strength;
private String durability;
private boolean canFly;
}
This is the most important class in this application, where all cassandra related configuration is placed and using this class we are connecting to cassandra and creating KEYSPACE and TABLES also while starting the application.
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.config.SchemaAction;
import org.springframework.data.cassandra.core.cql.keyspace.CreateKeyspaceSpecification;
import org.springframework.data.cassandra.core.cql.keyspace.DropKeyspaceSpecification;
import org.springframework.data.cassandra.core.cql.keyspace.KeyspaceOption;
import java.util.Collections;
import java.util.List;
@Configuration
public class CassandraConfig extends AbstractCassandraConfiguration {
@Value("${spring.data.cassandra.keyspace-name: simple_crud}")
private String KEYSPACE;
@Value("${spring.data.cassandra.contact-points: localhost}")
private String CONTACT_POINT;
@Value("${spring.data.cassandra.port: 9042}")
private int PORT;
@Override
public String getContactPoints() {
return CONTACT_POINT;
}
@Override
protected int getPort() {
return PORT;
}
@Override
public SchemaAction getSchemaAction() {
return SchemaAction.CREATE_IF_NOT_EXISTS;
}
@Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
return Collections.singletonList(CreateKeyspaceSpecification.createKeyspace(KEYSPACE)
.ifNotExists()
.with(KeyspaceOption.DURABLE_WRITES, true)
.withSimpleReplication(3L));
}
@Override
protected String getLocalDataCenter() {
return "datacenter1";
}
//@Override
//protected List<DropKeyspaceSpecification> getKeyspaceDrops() {
// return Collections.singletonList(DropKeyspaceSpecification.dropKeyspace(KEYSPACE));
//}
@Override
protected String getKeyspaceName() {
return KEYSPACE;
}
@Override
public String[] getEntityBasePackages() {
return new String[] {"com.arya.cassandra.model"};
}
}
In com.arya.cassandra.controller.SuperHeroController.java class, we have exposed 5 endpoints for basic CRUD operations
@RestController
@RequestMapping("/super-heroes")
public class SuperHeroController {
@GetMapping("/save")
public ResponseEntity<List<SuperHero>> save();
@GetMapping
public ResponseEntity<List<SuperHero>> findAll();
@GetMapping("/{id}")
public ResponseEntity<SuperHero> findById(@PathVariable String id);
@PostMapping
public ResponseEntity<SuperHero> save(@RequestBody SuperHero superHero);
@PutMapping
public ResponseEntity<SuperHero> update(@RequestBody SuperHero superHero);
@DeleteMapping("/{id}")
public ResponseEntity<SuperHero> delete(@PathVariable String id);
}
In com.arya.cassandra.repository.SuperHeroRepository.java, we are extending CassandraRepository<Class, ID>
interface which enables CRUD related methods.
@Repository
public interface SuperHeroRepository extends CassandraRepository<SuperHero, Long> {
}
In com.arya.cassandra.service.impl.SuperHeroServiceImpl.java, we are autowiring above interface using @Autowired
annotation and doing CRUD operation.
In com.arya.cassandra.controller.SuperHeroQueryController.java class Cassandra queries API Endpoints are placed.
we are autowiring SuperHeroQueryService interface using @Autowired
annotation and reaching to Service layer.
In com.arya.cassandra.service.impl.SuperHeroQueryServiceImpl.java,
we are autowiring SuperHeroQueryRepository interface using @Autowired
annotation and reaching to DAO layer.
In com.arya.cassandra.repository.impl.SuperHeroQueryRepositoryImpl.java,
we are autowiring CassandraOperations
interface which enables CRUD related methods.
@Autowired
private CassandraOperations cassandraTemplate;
GET Mapping http://localhost:8080/super-heroes - Get all Super Heroes
GET Mapping http://localhost:8080/super-heroes/1 - Get Super Hero by ID
POST Mapping http://localhost:8080/super-heroes - Add new Super Hero in DB
Request Body
{
"id": 1,
"name": "Tony",
"superName": "Iron Man",
"profession": "Business",
"age": 50,
"superPowers": {
"strength": "Suit",
"durability": "Month",
"canFly": true
}
}
PUT Mapping http://localhost:8080/super-heroes - Update existing Super Hero for given ID
Request Body
{
"id": 1,
"name": "Tony",
"superName": "Iron Man",
"profession": "Business",
"age": 50,
"superPowers": {
"strength": "Only if he is in a suit",
"durability": "Month",
"canFly": true
}
}
DELETE Mapping http://localhost:8080/super-heroes/1 - Delete Super Hero by ID