카테고리 없음

REST를 사용하여 Pivotal GemFire의 데이터에 액세스

경진 2021. 5. 16. 23:38

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를 사용하여 데이터 액세스 가이드를 읽어보십시오 .

필요한 것

이 가이드를 완료하는 방법

대부분의 Spring 시작하기 가이드 와 마찬가지로 처음부터 시작하여 각 단계를 완료하거나 이미 익숙한 기본 설정 단계를 건너 뛸 수 있습니다. 어느 쪽이든 작업 코드로 끝납니다.

처음부터 시작 하려면 Starting with Spring Initializr 로 이동 하십시오 .

기본 사항  건너 뛰 려면 다음을 수행하십시오.

완료되면 의 코드와 비교하여 결과를 확인할 수 있습니다 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 기반 백엔드 로 애플리케이션을 개발했습니다 .