1. 개요
이 사용방법(예제)에서는 경량 Java REST 프레임워크 RESTX 를 둘러봅니다 .
2. 특징
RESTX 프레임워크를 사용하면 RESTful API를 매우 쉽게 구축할 수 있습니다. 여기에는 JSON 제공 및 소비, 쿼리 및 경로 매개변수, 라우팅 및 필터링 메커니즘, 사용 통계 및 모니터링과 같은 REST 프레임워크에서 기대할 수 있는 모든 기본값이 있습니다.
RESTX는 또한 간편한 부트스트래핑을 위한 직관적인 관리 웹 콘솔 및 명령줄 설치 프로그램과 함께 제공됩니다.
또한 Apache License 2에 따라 라이선스가 부여되며 개발자 커뮤니티에서 유지 관리됩니다. RESTX에 대한 최소 Java 요구 사항은 JDK 7입니다.
3. 구성
RESTX는 Java 프로젝트를 빠르게 부트스트랩하는 데 유용한 편리한 셸/명령 앱과 함께 제공됩니다.
진행하기 전에 먼저 앱을 설치해야 합니다. 자세한 설치 지침은 여기에서 확인할 수 있습니다 .
4. 핵심 플러그인 설치
이제 셸 자체에서 앱을 만들 수 있도록 핵심 플러그인을 설치할 차례입니다.
RESTX 셸에서 다음 명령을 실행해 보겠습니다.
shell install
그런 다음 설치할 플러그인을 선택하라는 메시지가 표시됩니다. io.restx:restx-core-shell 을 가리키는 숫자를 선택해야 합니다 . 설치가 완료되면 셸이 자동으로 다시 시작됩니다.
5. 쉘 앱 부트스트랩
RESTX 셸을 사용하면 새 앱을 부트스트랩하는 것이 매우 편리합니다. 마법사 기반 사용방법(예제)를 제공합니다.
쉘에서 다음 명령을 실행하여 시작합니다.
app new
이 명령은 마법사를 트리거합니다. 그런 다음 기본 옵션을 사용하거나 요구 사항에 따라 변경할 수 있습니다.
pom.xml 을 생성하도록 선택했으므로 프로젝트를 모든 표준 Java IDE로 쉽게 가져올 수 있습니다.
경우에 따라 IDE 설정 을 조정해야 할 수도 있습니다 .
다음 단계는 프로젝트를 빌드하는 것입니다.
mvn clean install -DskipTests
빌드가 성공하면 AppServer 클래스를 IDE에서 Java 애플리케이션으로 실행할 수 있습니다 . 그러면 포트 8080에서 수신 대기하는 관리 콘솔로 서버가 시작됩니다.
http://127.0.0.1:8080/api/@/ui 로 이동하여 기본 UI를 볼 수 있습니다 .
/@/ 로 시작하는 경로는 RESTX에서 예약된 경로인 관리 콘솔에 사용됩니다.
관리 콘솔에 로그인하려면 기본 사용자 이름 "admin " 과 앱을 만들 때 제공한 비밀번호를 사용할 수 있습니다.
콘솔을 사용하기 전에 코드를 살펴보고 마법사가 생성한 내용을 이해해 봅시다.
6. RESTX 리소스
경로는 < main_package>.rest.HelloResource 클래스에서 정의됩니다.
@Component
@RestxResource
public class HelloResource {
@GET("/message")
@RolesAllowed(Roles.HELLO_ROLE)
public Message sayHello() {
return new Message().setMessage(String.format("hello %s, it's %s",
RestxSession.current().getPrincipal().get().getName(),
DateTime.now().toString("HH:mm:ss")));
}
}
RESTX가 Security 및 REST 바인딩을 위해 기본 J2EE 어노테이션을 사용한다는 것이 즉시 명백해집니다. 대부분의 경우 의존성 주입을 위해 자체 어노테이션을 사용합니다.
RESTX는 또한 메서드 매개변수를 요청에 매핑하기 위한 많은 합당한 기본값을 지원합니다 .
그리고 이러한 표준 어노테이션 외에도 RESTX가 인식 하는 리소스로 선언하는 @RestxResource 가 있습니다.
기본 경로는 src/main/webapp/WEB-INF/web.xml에 추가됩니다. 우리의 경우에는 /api 이므로 적절한 인증을 가정 하고 GET 요청을 http://localhost:8080/api/message 로 보낼 수 있습니다.
Message 클래스 는 RESTX가 JSON으로 직렬화하는 Java bean일 뿐입니다.
부트스트래퍼에서 생성한 HELLO_ROLE을 사용 하여 RolesAllowed 어노테이션을 지정하여 사용자 액세스를 제어합니다 .
7. 모듈 클래스
앞에서 언급했듯이 RESTX는 @Named 와 같은 J2EE 표준 의존성 주입 어노테이션을 사용하고 필요한 경우 @Module 및 @Provides 에 대한 Dagger 프레임워크에서 힌트를 얻어 자체적으로 발명합니다.
이를 사용하여 무엇보다도 관리자 암호를 정의하는 애플리케이션 기본 모듈을 생성합니다.
@Module
public class AppModule {
@Provides
public SignatureKey signatureKey() {
return new SignatureKey("restx-demo -44749418370 restx-demo 801f-4116-48f2-906b"
.getBytes(Charsets.UTF_8));
}
@Provides
@Named("restx.admin.password")
public String restxAdminPassword() {
return "1234";
}
@Provides
public ConfigSupplier appConfigSupplier(ConfigLoader configLoader) {
return configLoader.fromResource("restx/demo/settings");
}
// other provider methods to create components
}
@Module 은 Dagger의 @Module 또는 Spring의 @Configuration 과 유사하게 다른 구성 요소를 정의할 수 있는 클래스를 정의합니다 .
@Provides 는 Dagger의 @Provides 또는 Spring의 @Bean 과 같이 프로그래밍 방식으로 구성 요소를 노출합니다 .
마지막으로 @Named 어노테이션은 생성된 구성 요소의 이름을 나타내는 데 사용됩니다.
AppModule 은 또한 클라이언트에 전송된 콘텐츠에 서명하는 데 사용되는 SignatureKey 를 제공합니다. 예를 들어 샘플 앱에 대한 세션을 생성하는 동안 구성된 키로 서명된 쿠키를 설정합니다.
HTTP/1.1 200 OK
...
Set-Cookie: RestxSessionSignature-restx-demo="ySfv8FejvizMMvruGlK3K2hwdb8="; RestxSession-restx-demo="..."
...
자세한 내용은 RESTX의 구성 요소 팩터리/의존성 주입 설명서 를 확인하세요 .
8. 런처 클래스
마지막으로 AppServer 클래스는 임베디드 Jetty 서버에서 표준 Java 앱으로 애플리케이션을 실행하는 데 사용됩니다.
public class AppServer {
public static final String WEB_INF_LOCATION = "src/main/webapp/WEB-INF/web.xml";
public static final String WEB_APP_LOCATION = "src/main/webapp";
public static void main(String[] args) throws Exception {
int port = Integer.valueOf(Optional.fromNullable(System.getenv("PORT")).or("8080"));
WebServer server =
new Jetty8WebServer(WEB_INF_LOCATION, WEB_APP_LOCATION, port, "0.0.0.0");
System.setProperty("restx.mode", System.getProperty("restx.mode", "dev"));
System.setProperty("restx.app.package", "restx.demo");
server.startAndAwait();
}
}
여기에서 dev 모드는 개발 단계에서 개발 피드백 루프를 단축하는 자동 컴파일과 같은 기능을 활성화하는 데 사용됩니다.
앱을 war (웹 아카이브) 파일로 패키징하여 독립 실행형 J2EE 웹 컨테이너에 배포할 수 있습니다.
다음 섹션에서 앱을 테스트하는 방법을 알아보겠습니다.
9. 사양을 사용한 통합 테스트
RESTX의 강력한 기능 중 하나는 "스펙"이라는 개념입니다. 샘플 사양 은 다음과 같습니다.
title: should admin say hello
given:
- time: 2013-08-28T01:18:00.822+02:00
wts:
- when: |
GET hello?who=xavier
then: |
{"message":"hello xavier, it's 01:18:00"}
테스트는 기본적으로 시스템의 현재 상태( 주어진 )가 주어진 특정 요청( 언제 ) 에 대해 API가 어떻게 응답해야 하는지( 다음 )를 정의하는 YAML 파일 내의 주어진-언제 -Then 구조 로 작성됩니다 .
src/test/resources 의 HelloResourceSpecTest 클래스는 위 사양에 작성된 테스트를 트리거합니다.
@RunWith(RestxSpecTestsRunner.class)
@FindSpecsIn("specs/hello")
public class HelloResourceSpecTest {}
RestxSpecTestsRunner 클래스는 사용자 정의 JUnit 러너 입니다. 여기에는 다음과 같은 사용자 지정 JUnit 규칙이 포함되어 있습니다.
- 임베디드 서버 설정
- 시스템 상태 준비(사양의 지정된 섹션에 따라)
- 지정된 요청을 발행하고
- 예상 응답 확인
@FindSpecsIn 어노테이션은 테스트를 실행해야 하는 사양 파일의 경로를 가리킵니다 .
이 사양은 통합 테스트를 작성하고 API 문서에서 예제를 제공하는 데 도움이 됩니다. 사양은 HTTP 요청을 모의하고 요청/응답 쌍을 기록 하는 데에도 유용합니다 .
10. 수동 테스트
HTTP를 통해 수동으로 테스트할 수도 있습니다. 먼저 로그인해야 하며 이를 위해서는 RESTX 콘솔에서 관리자 비밀번호를 해시해야 합니다.
hash md5 <clear-text-password>
그런 다음 이를 /sessions Endpoints으로 전달할 수 있습니다.
curl -b u1 -c u1 -X POST -H "Content-Type: application/json"
-d '{"principal":{"name":"admin","passwordHash":"1d528266b85cf052803a57288"}}'
http://localhost:8080/api/sessions
(Windows 사용자는 curl을 먼저 다운로드 해야 합니다.)
이제 /message 요청의 일부로 세션을 사용하는 경우:
curl -b u1 "http://localhost:8080/api/message?who=restx"
그러면 다음과 같은 결과를 얻게 됩니다.
{"message" : "hello admin, it's 09:56:51"}
11. 관리 콘솔 살펴보기
관리 콘솔은 앱을 제어하는 데 유용한 리소스를 제공합니다.
http://127.0.0.1:8080/admin/@/ui 로 이동하여 주요 기능을 살펴보겠습니다 .
11.1. API 문서
API 문서 섹션에는 모든 옵션을 포함하여 사용 가능한 모든 경로가 나열됩니다.
개별 경로를 클릭하고 콘솔 자체에서 사용해 볼 수 있습니다.
11.2. 모니터링
JVM 메트릭 섹션에는 활성 세션, 메모리 사용량 및 스레드 덤프가 포함된 애플리케이션 메트릭이 표시됩니다 .
Application Metrics 에는 기본적으로 모니터링되는 주로 두 가지 범주의 요소가 있습니다 .
- BUILD 는 응용 프로그램 구성 요소의 인스턴스화에 해당합니다.
- HTTP 는 RESTX에서 처리하는 HTTP 요청에 해당합니다.
11.3. 통계
RESTX를 사용하면 사용자가 애플리케이션에서 익명 통계를 수집하고 공유하여 RESTX 커뮤니티에 정보를 제공하도록 선택할 수 있습니다. restx-stats-admin 모듈 을 제외하여 쉽게 옵트아웃할 수 있습니다 .
통계는 기본 OS 및 JVM 버전과 같은 것을 보고합니다.
이 페이지에는 민감한 정보가 표시되므로 해당 구성 옵션을 검토해야 합니다 .
이 외에도 관리 콘솔은 다음과 같은 도움을 줄 수 있습니다.
- 서버 로그 확인 (Logs)
- 발생한 오류 보기(오류)
- 환경 변수 확인(구성)
12. 승인
RESTX 엔드포인트는 기본적으로 보호됩니다. 즉, 엔드포인트에 대해 다음을 의미합니다.
@GET("/greetings/{who}")
public Message sayHello(String who) {
return new Message(who);
}
인증 없이 호출하면 기본적으로 401 이 반환 됩니다.
Endpoints을 공개하려면 메서드 또는 클래스 수준에서 @PermitAll 어노테이션 을 사용해야 합니다 .
@PermitAll
@GET("/greetings/{who}")
public Message sayHello(String who) {
return new Message(who);
}
클래스 수준에서 모든 메서드는 공개됩니다.
또한 프레임워크는 @RolesAllowed 어노테이션을 사용하여 사용자 역할을 지정할 수도 있습니다.
@RolesAllowed("admin")
@GET("/greetings/{who}")
public Message sayHello(String who) {
return new Message(who);
}
이 어노테이션을 사용하여 RESTX는 인증된 사용자에게 할당된 관리자 역할도 있는지 확인합니다. 관리자 역할이 없는 인증된 사용자가 엔드포인트에 액세스하려고 시도하는 경우 애플리케이션은 401 대신 403 을 반환합니다 .
기본적으로 사용자 역할 및 자격 증명은 파일 시스템의 별도 파일에 저장됩니다.
따라서 암호화된 비밀번호가 있는 사용자 ID는 /data/credentials.json 파일에 저장됩니다.
{
"user1": "$2a$10$iZluUbCseDOvKnoe",
"user2": "$2a$10$oym3Swr7pScdiCXu"
}
그리고 사용자 역할은 /data/users.json 파일에 정의됩니다.
[
{"name":"user1", "roles": ["hello"]},
{"name":"user2", "roles": []}
]
샘플 앱에서 파일 은 FileBasedUserRepository 클래스 를 통해 AppModule 에 로드됩니다.
new FileBasedUserRepository<>(StdUser.class, mapper,
new StdUser("admin", ImmutableSet.<String> of("*")),
Paths.get("data/users.json"), Paths.get("data/credentials.json"), true)
StdUser 클래스는 사용자 개체를 보유합니다 . 사용자 지정 사용자 클래스일 수 있지만 JSON으로 직렬화할 수 있어야 합니다.
물론 데이터베이스에 도달하는 것과 같은 다른 UserRepository 구현을 사용할 수 있습니다.
13. 결론
이 사용방법(예제)에서는 경량 Java 기반 RESTX 프레임워크에 대한 개요를 제공했습니다.
프레임워크는 아직 개발 중이며 이를 사용하는 데 약간의 거친 부분이 있을 수 있습니다. 자세한 내용 은 공식 문서 를 확인 하세요.
샘플 부트스트랩 앱은 GitHub 리포지토리 에서 사용할 수 있습니다 .