REST를 사용하여 Pivotal GemFire의 데이터에 액세스
이 가이드 는 하이퍼 미디어 기반 REST-ful 프런트 엔드를 통해 Apache Geode에 저장된 데이터에 액세스하는 애플리케이션을 만드는 프로세스를 안내합니다 .
무엇을 만들 것인가
SpringData REST를 사용하여 Apache Geode IMDG (In-Memory Data Grid)에 저장된 객체 를 만들고 검색 할 수있는 Spring 웹 애플리케이션을 빌드합니다 . SpringData REST는 Spring HATEOAS 및 SpringData for Apache Geode 의 기능을 자동으로 결합합니다.Person
SpringData REST는 또한 SpringData JPA , SpringData MongoDB 및 SpringData Neo4j 를 백엔드 데이터 저장소로 지원하지만이 가이드의 일부는 아닙니다. |
Apache Geode 개념에 대한 일반적인 지식과 Apache Geode에서 데이터에 액세스하려면 Apache Geode를 사용하여 데이터 액세스 가이드를 읽어보십시오 . |
필요한 것
- 약 15 분
- 자주 사용하는 텍스트 편집기 또는 IDE
- JDK 1.8 이상
- Gradle 4 이상 또는 Maven 3.2 이상
- 코드를 IDE로 직접 가져올 수도 있습니다.
이 가이드를 완료하는 방법
대부분의 Spring 시작하기 가이드 와 마찬가지로 처음부터 시작하여 각 단계를 완료하거나 이미 익숙한 기본 설정 단계를 건너 뛸 수 있습니다. 어느 쪽이든 작업 코드로 끝납니다.
처음부터 시작 하려면 Starting with Spring Initializr 로 이동 하십시오 .
기본 사항 을 건너 뛰 려면 다음을 수행하십시오.
- 이 가이드의 소스 저장소를 다운로드 하고 압축을 풀거나 Git 을 사용하여 복제합니다 .git clone https://github.com/spring-guides/gs-accessing-gemfire-data-rest.git
- CD로 gs-accessing-gemfire-data-rest/initial
- 도메인 개체 만들기로 이동 합니다 .
완료되면 의 코드와 비교하여 결과를 확인할 수 있습니다 gs-accessing-gemfire-data-rest/complete.
Spring Initializr로 시작
모든 Spring 애플리케이션의 경우 Spring Initializr로 시작해야 합니다 . Spring Initializr는 애플리케이션에 필요한 모든 종속성을 가져 오는 빠른 방법을 제공하며 많은 설정을 수행합니다. 이 예제에는 " Spring for Apache Geode "종속성 이 필요합니다 .
다음 목록은 pom.xmlMaven을 사용할 때 의 예제 파일을 보여줍니다 .
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
</parent>
<groupId>org.springframework</groupId>
<artifactId>gs-accessing-gemfire-data-rest</artifactId>
<version>0.1.0</version>
<properties>
<spring-shell.version>1.2.0.RELEASE</spring-shell.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-geode</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell</artifactId>
<version>${spring-shell.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
다음 목록은 build.gradleGradle을 사용할 때 의 예제 파일을 보여줍니다 .
plugins {
id 'org.springframework.boot' version '2.4.1'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id "io.freefair.lombok" version "5.3.0"
id 'java'
}
apply plugin: 'eclipse'
apply plugin: 'idea'
group = "org.springframework"
version = "0.1.0"
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-data-rest"
implementation "org.springframework.data:spring-data-geode"
implementation "org.projectlombok:lombok"
runtimeOnly "org.springframework.shell:spring-shell:1.2.0.RELEASE"
testImplementation "org.springframework.boot:spring-boot-starter-test"
}
test {
useJUnitPlatform()
}
bootJar {
baseName = 'gs-accessing-gemfire-data-rest'
version = '0.1.0'
}
도메인 개체 만들기
사람을 표시 할 새 도메인 개체를 만듭니다.
src/main/java/hello/Person.java
package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.gemfire.mapping.annotation.Region;
import lombok.Data;
@Data
@Region("People")
public class Person {
private static AtomicLong COUNTER = new AtomicLong(0L);
@Id
private Long id;
private String firstName;
private String lastName;
@PersistenceConstructor
public Person() {
this.id = COUNTER.incrementAndGet();
}
}
에 Person성과 이름이 있습니다. Apache Geode 도메인 개체에는 ID가 필요하므로 AtomicLong각 Person개체 생성에 따라 증가하는 데 사용됩니다 .
개인 저장소 만들기
다음 으로 Apache Geode에 저장된 개체 를 유지 / 접근하기 위해 간단한 저장소 를 만들어야합니다 Person.
src/main/java/hello/PersonRepository.java
package hello;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends CrudRepository<Person, Long> {
List<Person> findByLastName(@Param("name") String name);
}
이 저장소 는 인터페이스이며 Person객체 와 관련된 다양한 데이터 액세스 작업 (예 : 기본 CRUD 및 간단한 쿼리)을 수행 할 수 있습니다 . 확장하여 이러한 작업을 가져옵니다 CrudRepository.
런타임시 Apache Geode 용 SpringData 는이 인터페이스의 구현을 자동으로 생성합니다. 그런 다음 SpringData REST는 @RepositoryRestResource 주석을 사용하여 Spring MVC가 .NET에서 REST-ful 엔드 포인트를 생성하도록 지시합니다 /people.
@RepositoryRestResource저장소 를 내보내는 데는 필요하지 않습니다 . /people기본값 대신 사용 하는 것과 같은 내보내기 세부 정보를 변경하는 데만 사용됩니다 /persons. |
여기에서는을 Person기반으로 하는 개체 목록을 검색하는 사용자 지정 쿼리도 정의했습니다 lastName. 이 가이드에서 더 아래로 호출하는 방법을 볼 수 있습니다.
응용 프로그램을 실행 가능하게 만들기
이 서비스를 외부 애플리케이션 서버에 배포하기 위해 기존 WAR 파일 로 패키지화 할 수 있지만 아래에 설명 된 더 간단한 접근 방식은 독립형 애플리케이션을 만듭니다. 좋은 오래된 Java main()메소드로 구동되는 하나의 실행 가능한 JAR 파일에 모든 것을 패키징합니다 . 그 과정에서 외부 서블릿 컨테이너에 배포하는 대신 Tomcat 서블릿 컨테이너를 HTTP 런타임으로 포함하는 Spring의 지원을 사용 합니다.
src/main/java/hello/Application.java
package hello;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;
@SpringBootApplication
@ClientCacheApplication(name = "AccessingGemFireDataRestApplication")
@EnableEntityDefinedRegions(
basePackageClasses = Person.class,
clientRegionShortcut = ClientRegionShortcut.LOCAL
)
@EnableGemfireRepositories
@SuppressWarnings("unused")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication 다음을 모두 추가하는 편리한 주석입니다.
- @Configuration: 애플리케이션 컨텍스트에 대한 Bean 정의 소스로 클래스에 태그를 지정합니다.
- @EnableAutoConfiguration: Spring Boot에 클래스 경로 설정, 기타 Bean 및 다양한 속성 설정을 기반으로 Bean 추가를 시작하도록 지시합니다. 예를 spring-webmvc들어이 클래스 경로에있는 경우이 주석은 애플리케이션을 웹 애플리케이션으로 플래그 지정하고 DispatcherServlet.
- @ComponentScan: Spring에 hello패키지 에서 다른 구성 요소, 구성 및 서비스를 찾도록 지시 하여 컨트롤러를 찾을 수 있도록합니다.
이 main()방법은 Spring Boot의 SpringApplication.run()방법을 사용하여 애플리케이션을 시작합니다. XML이 한 줄도 없다는 것을 알았습니까? web.xml파일 도 없습니다 . 이 웹 애플리케이션은 100 % 순수 Java이며 배관이나 인프라를 구성 할 필요가 없습니다.
@EnableGemfireRepositories주석은 활성화 아파치 오드을 위해 봄 데이터 저장소 . Apache Geode 용 SpringData 는 PersonRepository인터페이스 의 구체적인 구현을 생성하고 Apache Geode 의 임베디드 인스턴스와 통신하도록 구성합니다.
실행 가능한 JAR 빌드
Gradle 또는 Maven을 사용하여 명령 줄에서 애플리케이션을 실행할 수 있습니다. 필요한 모든 종속성, 클래스 및 리소스를 포함하는 단일 실행 가능 JAR 파일을 빌드하고 실행할 수도 있습니다. 실행 가능한 jar를 빌드하면 개발 라이프 사이클 전반에 걸쳐 다양한 환경 등에서 애플리케이션으로 서비스를 쉽게 제공하고 버전을 지정하고 배포 할 수 있습니다.
Gradle을 사용하는 경우 ./gradlew bootRun. 또는 ./gradlew build다음과 같이을 사용하여 JAR 파일을 빌드 한 후 실행할 수 있습니다.
java -jar build/libs/gs-accessing-gemfire-data-rest-0.1.0.jar
Maven을 사용하는 경우 ./mvnw spring-boot:run. 또는 ./mvnw clean package다음 과 같이 JAR 파일을 빌드 한 다음 JAR 파일 을 실행할 수 있습니다.
java -jar target/gs-accessing-gemfire-data-rest-0.1.0.jar
여기에 설명 된 단계는 실행 가능한 JAR을 생성합니다. 클래식 WAR 파일을 빌드 할 수도 있습니다 . |
로깅 출력이 표시됩니다. 서비스는 몇 초 내에 가동 및 실행되어야합니다.
응용 프로그램 테스트
이제 애플리케이션이 실행 중이므로 테스트 할 수 있습니다. 원하는 REST 클라이언트를 사용할 수 있습니다. 다음 예제에서는 * nix 도구를 사용합니다 curl.
먼저 최상위 서비스를보고 싶습니다.
$ curl http://localhost:8080
{
"_links" : {
"people" : {
"href" : "http://localhost:8080/people"
}
}
}
여기에서이 서버가 제공하는 것을 처음으로 엿볼 수 있습니다. 이 사람들 에있는 정보 링크 에 http : // localhost를 : 8080 / 인 . Apache Geode 용 SpringData 는 다른 SpringData REST 가이드처럼 페이지 매김을 지원하지 않으므로 추가 탐색 링크가 없습니다.
SpringData REST는 JSON 출력에 HAL 형식 을 사용합니다 . 유연하고 제공되는 데이터에 인접한 링크를 제공하는 편리한 방법을 제공합니다. |
$ curl http://localhost:8080/people
{
"_links" : {
"search" : {
"href" : "http://localhost:8080/people/search"
}
}
}
새로 만들 시간입니다 Person!
$ curl -i -X POST -H "Content-Type:application/json" -d '{ "firstName" : "Frodo", "lastName" : "Baggins" }' http://localhost:8080/people
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Location: http://localhost:8080/people/1
Content-Length: 0
Date: Wed, 05 Mar 2014 20:16:11 GMT
- -i헤더를 포함한 응답 메시지를 볼 수 있습니다. 새로 생성 된 URI Person가 표시됩니다.
- -X POSTPOST새 항목을 작성하기 위해 HTTP 요청을 발행합니다.
- -H "Content-Type:application/json" 애플리케이션이 페이로드에 JSON 객체가 포함되어 있음을 알 수 있도록 콘텐츠 유형을 설정합니다.
- -d '{ "firstName" : "Frodo", "lastName" : "Baggins" }' 전송되는 데이터입니다
이전 POST작업에 Location헤더가 어떻게 포함 되는지 확인하십시오 . 여기에는 새로 생성 된 리소스의 URI가 포함됩니다. SpringData REST에는 또한 두 가지 메소드가 RepositoryRestConfiguration.setReturnBodyOnCreate(…)있으며 setReturnBodyOnCreate(…)방금 생성 된 리소스의 표현을 즉시 반환하도록 프레임 워크를 구성하는 데 사용할 수 있습니다. |
여기에서 모든 사람을 쿼리 할 수 있습니다.
$ curl http://localhost:8080/people
{
"_links" : {
"search" : {
"href" : "http://localhost:8080/people/search"
}
},
"_embedded" : {
"persons" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
} ]
}
}
사람들 수집 자원은 프로와 목록이 포함되어 있습니다. 자체 링크가 어떻게 포함되어 있는지 확인 하십시오. SpringData REST는 또한 Evo Inflector 를 사용 하여 그룹화를 위해 엔티티 이름을 복수화합니다.
개별 레코드를 직접 쿼리 할 수 있습니다.
$ curl http://localhost:8080/people/1
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
}
이것은 순전히 웹 기반으로 보일 수 있지만 배후에서는 임베디드 Apache Geode 데이터베이스와 통신합니다. |
이 가이드에는 도메인 개체가 하나만 있습니다. 도메인 객체가 서로 관련되어있는 더 복잡한 시스템에서 SpringData REST는 연결된 레코드를 탐색하는 데 도움이되는 추가 링크를 렌더링합니다.
모든 사용자 지정 쿼리를 찾습니다.
$ curl http://localhost:8080/people/search
{
"_links" : {
"findByLastName" : {
"href" : "http://localhost:8080/people/search/findByLastName{?name}",
"templated" : true
}
}
}
HTTP 쿼리 매개 변수를 포함한 쿼리의 URL을 볼 수 있습니다 name. 아시다시피, 이것은 @Param("name")인터페이스에 포함 된 주석 과 일치합니다 .
findByLastName쿼리 를 사용하려면 다음과 같이하십시오.
$ curl http://localhost:8080/people/search/findByLastName?name=Baggins
{
"_embedded" : {
"persons" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
} ]
}
}
List<Person>코드에서 반환하도록 정의 했으므로 모든 결과를 반환합니다. return 만 반환하도록 정의했다면 반환 Person할 Person객체 중 하나를 선택 합니다. 이것은 예측할 수 없기 때문에 여러 항목을 반환 할 수있는 쿼리에 대해서는 그렇게하고 싶지 않을 것입니다.
당신은 문제도 할 수있는 PUT, PATCH그리고 DELETE기존 레코드를 대체 업데이트 또는 삭제 중 하나에 REST 호출합니다.
$ curl -X PUT -H "Content-Type:application/json" -d '{ "firstName": "Bilbo", "lastName": "Baggins" }' http://localhost:8080/people/1
$ curl http://localhost:8080/people/1
{
"firstName" : "Bilbo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
}
$ curl -X PATCH -H "Content-Type:application/json" -d '{ "firstName": "Bilbo Jr." }' http://localhost:8080/people/1
$ curl http://localhost:8080/people/1
{
"firstName" : "Bilbo Jr.",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
}
PUT전체 레코드를 대체합니다. 제공되지 않은 필드는로 대체됩니다 null. PATCH항목의 하위 집합을 업데이트하는 데 사용할 수 있습니다. |
레코드를 삭제할 수 있습니다.
$ curl -X DELETE http://localhost:8080/people/1
$ curl http://localhost:8080/people
{
"_links" : {
"search" : {
"href" : "http://localhost:8080/people/search"
}
}
}
이 하이퍼 미디어 기반 인터페이스 의 매우 편리한 측면 은 사용하는 모든 REST-ful 엔드 포인트 curl(또는 사용중인 REST 클라이언트)를 검색하는 방법입니다. 고객과 공식 계약 또는 인터페이스 문서를 교환 할 필요가 없습니다.
요약
축하합니다! 하이퍼 미디어 기반 RESTful 프런트 엔드와 Apache Geode 기반 백엔드 로 애플리케이션을 개발했습니다 .