반응형

서론

AWS의 대표적인 NoSQL 서비스인 DynamoDB를 Spring Boot로 CRUD 조작 하는 예제를 작성해 보았습니다.

개인 PC에서 개발을 할 경우 물론 credential을 이용해 개인 PC에서 AWS 클라우드 상에 있는 DynamoDB를 직접 조작해 볼 수 있겠지만 본 예제에서는 빠른 실행을 위해 아래의 링크에 설명된 로컬 PC 설치 버전의 DynamoDB를 이용한 예제를 설명드립니다.

로컬 버전의 DynamoDB 설치를 하지 않으신 분들은 아래의 링크를 이용해 테스해 보시기를 권장드립니다.

 

 

개인 PC에 DynamoDB를 설치해 테스트 해보자

서론 AWS의 DynamoDB는 AWS의 대표적인 NoSQL Database입니다. 이번 장에서는 Java를 가지고 DynamoDB를 Local환경에서 개발 및 테스트 해보는 것을 알아 보도록 하겠습니다. 이번 포스팅을 따라해보기 위해서

sharplee7.tistory.com

 

본론

먼저 git에서 테스트를 위한 샘플을 아래의 git 명령어를 통해 레파지토리를 clone 하도록 합니다.

git clone https://github.com/sharplee7/java-dynamodb-example.git
 

GitHub - sharplee7/java-dynamodb-example: spring boot dynamodb example

spring boot dynamodb example. Contribute to sharplee7/java-dynamodb-example development by creating an account on GitHub.

github.com

 

본 예제는 아래의 디렉토리에서 볼 수 있듯이 customer와 music(MusicCollection) 두개의 예제로 구성되어 있습니다.

서론에서 이야기 했듯이 로컬 PC에 8000번으로 dynamodb를 실행시켰다면 별도의 테이블 생성이나, 설정 필요 없이 본 예제 프로그램을 실행시켜 바로 CRUD 예제를 확인해 볼 수 있습니다.

 

 

applicaiton.properties

aws.dynamodb.endpoint=http://localhost:8000
aws.region=ap-northeast-2
# If you use local dynamodb, use bollow key
# But if you use cloud version, please use your accessKey and secretKey
aws.accessKey= accesskey
aws.secretKey= secretKey
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
  • 본 예제에서 dynamodb의 endpoint는 localhost로 되어 있습니다.
  • region은 한국 리전으로(localhost 사용 시 큰 의미는 없습니다.) 설정했습니다.
  • aws 계정 configuration을 위한 accessKey와 secretKey는 서버 사용시에 서버에 설정된 값을 입력합니다. (여기서는 localhost이기 때문에 큰 의미가 없습니다.)
  • spring.mvc.pathmatch.matching-strategy=ant_path_matcher 이 값은 spring boot 버전 호환성을 위해 그대로 사용합니다.

 

DynamoDBConfiguration.java

applicaiton.properties에 설정된 설정 값을 이용해 DynamoDB 접속을 통해 CRUD 작업을 할 수 있는 객체를 정의합니다.

@Configuration
public class DynamoDBConfiguration {
    @Value("${aws.dynamodb.endpoint}")
    private String endPoint;

    @Value("${aws.region}")
    private String region;

    @Value("${aws.accessKey}")
    private String accessKey;

    @Value("${aws.secretKey}")
    private String secretKey;

    @Bean
    public DynamoDBMapper dynamoDBMapper() {
        DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder()
                .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER)
                .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT)
                .withTableNameOverride(null)
                .withPaginationLoadingStrategy(DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING)
                .build();

        return new DynamoDBMapper(amazonDynamoDB(), mapperConfig);
    }

    @Primary
    @Bean
    public AWSCredentialsProvider awsCredentialsProvider() {
        return new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey,secretKey));
    }

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        return AmazonDynamoDBClientBuilder
                .standard()
                .withEndpointConfiguration(
                        new AwsClientBuilder.EndpointConfiguration(endPoint, region)
                )
                .withCredentials(awsCredentialsProvider())
                .build();
    }
}

 

Customer.java

DynamoDB에서 사용할 Table입니다. 이름은 customer이며 Table의 key 값은 customerId를 사용합니다.

...
@DynamoDBTable(tableName = "customer")
public class Customer {

    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    private String customerId;

    @DynamoDBAttribute
    private String firstName;

    @DynamoDBAttribute
    private String lastName;

    @DynamoDBAttribute
    private String email;

    @DynamoDBAttribute
    private Address address;

    public String getCustomerId() {
        return customerId;
    }

    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
         ...

 

CustomerRepository.java

CRUD 작업을 위한 레파지토리 클래스입니다. Controller로부터 파라미터로 받은 Customer의 내용을 DynamoDB의 customer 테이블에 입력, 수정, 삭제, 조회 할 수 있습니다.

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue;
import com.example.dynamodbdemo.customer.domain.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class CustomerRepository {

    @Autowired
    private DynamoDBMapper dynamoDBMapper;
    
    // 생성
    public Customer saveCustomer(Customer customer) {
        dynamoDBMapper.save(customer);
        return customer;
    }
    
    // 조회
    public Customer getCustomerById(String customerId) {
        return dynamoDBMapper.load(Customer.class, customerId);
    }

    // 삭제
    public String deleteCustomerById(String customerId) {
        dynamoDBMapper.delete(dynamoDBMapper.load(Customer.class, customerId));
        return "Customer Id : "+ customerId +" Deleted!";
    }

    // 수정
    public String updateCustomer(Customer customer) {
        dynamoDBMapper.save(customer,
                new DynamoDBSaveExpression()
                        .withExpectedEntry("customerId",
                                new ExpectedAttributeValue(
                                        new AttributeValue().withS(customer.getCustomerId())
                                )));
        return customer.getCustomerId();
    }
}

CustomerController.java

CustomerController에는 curl 혹은 swagger-ui를 통해 접근 할 수 있으며 URL은 /customer가 있습니다. CRUD에 따라 POST, PUT, GET, DELETE라는 http method를 이용하고 있습니다.

@RestController
public class CustomerController {

    @Autowired
    private CustomerService customerService;

    @PostMapping("/customer")
    public Customer saveCustomer(@RequestBody Customer customer) {
        return customerService.saveCustomer(customer);
    }

    @GetMapping("/customer/{id}")
    public Customer getCustomerById(@PathVariable("id") String customerId) {
        return customerService.getCustomerById(customerId);
    }

    @DeleteMapping("/customer/{id}")
    public String deleteCustomerById(@PathVariable("id") String customerId) {
        return  customerService.deleteCustomerById(customerId);
    }

    @PutMapping("/customer")
    public String updateCustomer(@RequestBody Customer customer) {
        return customerService.updateCustomer(customer);
    }
}

 

swagger-ui 접속 및 customer 데이터 입력

DynamodbDemoApplication을 시작한 후 다음의 URL에 접속하도록 합니다. (사전에 local PC에 dynamodb가 실행되고 있어야 합니다.)

http://localhost:8080/swagger-ui

Customer Controller의 POST 메소드에 다음과 같은 테스트 값을 입력해 보도록 합니다.

{
  "address": {
    "city": "seoul",
    "country": "south korea",
    "line1": "gangnam-gu"
  },
  "customerId": "admin",
  "email": "admin@",
  "firstName": "admin",
  "lastName": "istrator"
}

'Execute'를 클릭해 데이터가 정상적으로 입력되는지 리턴 코드를 확인합니다.

방금 입력된 값을 아래의 CLI를 통해 확인해 볼 수 있습니다. 

aws dynamodb query --table-name customer --key-condition-expression "customerId = :v1" --expression-attribute-values  '{":v1":{"S":"admin"}}' --endpoint-url=http://localhost:8000

 

입력 데이터 조회

Swagger-Ui화면에서 Customer의 GET 메소드를 선택해 앞서 입력했던 'admin'을 조회해 보도록 합니다.

아래의 이미지 처럼 앞서 입력했던 값이 조회되는 것을 확인 할 수 있습니다.

 

입력데이터 수정

Swagger-Ui화면에서 Customer의 PUT 메소드를 선택해 앞서 입력했던 admin 사용자의 값을 다음과 같이 변경해 보도록 하겠습니다.

- line1의 값을 gangnam-gu 에서 '231, Teheran-ro' 로 변경해 보았습니다.

{
  "address": {
    "city": "seoul",
    "country": "south korea",
    "line1": "231, Teheran-ro"
  },
  "customerId": "admin",
  "email": "admin@",
  "firstName": "admin",
  "lastName": "istrator"
}

다시 Swagger-Ui에서 GET 메소드를 클릭해 customerId 항목에 admin을 입력 후 조회하면 변경된 값으로 저장된 것을 확인 할 수 있습니다.

 

입력데이터 삭제

Swagger-Ui화면에서 Customer의 DELETE 메소드를 선택해 앞서 입력했던 admin 을 파라미터로 입력해 삭제 할 수 있습니다.

삭제 후 Swagger-Ui의 GET 메뉴에서 'admin'으로 조회 했을 경우 더이상 데이터가 조회되지 않는 것을 확인 하실 수 있습니다.

 

결론

지금까지 Java Spring Boot를 이용해 AWS의 DynamoDB의 테이블에 대한 CRUD 예제를 알아 보았습니다.

감사합니다.

반응형

+ Recent posts