From 5b7db23aaacbb08a8242b1a77bd39bc19139526c Mon Sep 17 00:00:00 2001 From: Alex Shpak Date: Sun, 30 Sep 2018 01:31:24 +0200 Subject: Add exampleSite --- exampleSite/config.yml | 18 +++++ exampleSite/content/_index.md | 77 ++++++++++++++++++++++ .../content/docs/dropwizard-configuration.md | 35 ++++++++++ exampleSite/content/docs/jersey-configuration.md | 20 ++++++ exampleSite/content/docs/rx-jersey-client.md | 60 +++++++++++++++++ exampleSite/content/docs/rx-jersey-server.md | 64 ++++++++++++++++++ exampleSite/content/menu/index.md | 12 ++++ 7 files changed, 286 insertions(+) create mode 100644 exampleSite/config.yml create mode 100644 exampleSite/content/_index.md create mode 100644 exampleSite/content/docs/dropwizard-configuration.md create mode 100644 exampleSite/content/docs/jersey-configuration.md create mode 100644 exampleSite/content/docs/rx-jersey-client.md create mode 100644 exampleSite/content/docs/rx-jersey-server.md create mode 100644 exampleSite/content/menu/index.md (limited to 'exampleSite') diff --git a/exampleSite/config.yml b/exampleSite/config.yml new file mode 100644 index 0000000..378f01f --- /dev/null +++ b/exampleSite/config.yml @@ -0,0 +1,18 @@ +baseURL: http://example.org +title: Rx Jersey +theme: book + +# Book configuration +disablePathToLower: true + +params: + # show or hide table of contents for page + BookShowToC: true + + # Set bundle to render side menu + # if not specified file structure and weights will be used + BookMenuBundle: /menu + + # specify section of content to render as menu + # if bookMenuBundle is not set, 'docs' is value by default + BookSection: docs diff --git a/exampleSite/content/_index.md b/exampleSite/content/_index.md new file mode 100644 index 0000000..0c7a403 --- /dev/null +++ b/exampleSite/content/_index.md @@ -0,0 +1,77 @@ +--- +title: Introduction +type: docs +--- + +# RxJersey - Reactive Jersey Feature + +[![Build Status](https://travis-ci.org/alex-shpak/rx-jersey.svg?branch=master)](https://travis-ci.org/alex-shpak/rx-jersey) +![Maven Central](https://img.shields.io/maven-central/v/net.winterly.rxjersey/core-server.svg) + +RxJersey is RxJava extension for [Jersey](https://jersey.java.net/) framework providing non-blocking Jax-RS server and client. +RxJersey target is to handle large amount requests in small static set of threads, which is highly suitable for microservice applications. + +Library uses Jersey 2 async support with `@Suspended` and `AsyncResponse` under the hood. + +## Features +- [x] RxJava Support +- [x] RxJava 2 Support +- [x] RxJava Proxy Client +- [x] Async Request Interceptors +- [x] Dropwizard bundle + +## Roadmap +- [ ] Futures support +- [ ] Vert.x integration +- [ ] Improved proxy client + + +## Maven Artifacts +### Maven Central +``` +compile "net.winterly.rxjersey:dropwizard:$rxJerseyVersion" +compile "net.winterly.rxjersey:rxjava-client:$rxJerseyVersion" +compile "net.winterly.rxjersey:rxjava-server:$rxJerseyVersion" +compile "net.winterly.rxjersey:rxjava2-client:$rxJerseyVersion" +compile "net.winterly.rxjersey:rxjava2-server:$rxJerseyVersion" +``` + +### JitPack +Most recent snapshot is available via [JitPack](https://jitpack.io/#alex-shpak/rx-jersey/) +``` +compile "com.github.alex-shpak.rx-jersey:dropwizard:$rxJerseyVersion" +compile "com.github.alex-shpak.rx-jersey:rxjava-client:$rxJerseyVersion" +compile "com.github.alex-shpak.rx-jersey:rxjava-server:$rxJerseyVersion" +compile "com.github.alex-shpak.rx-jersey:rxjava2-client:$rxJerseyVersion" +compile "com.github.alex-shpak.rx-jersey:rxjava2-server:$rxJerseyVersion" +``` + + +## Example +```java +@Path("/example/") +public class GithubResource { + + @Remote("https://api.github.com/") + private GithubApi githubApi; + + @GET + @Path("github") + public Single getRepository() { + return githubApi.getRepository("alex-shpak", "rx-jersey").toSingle(); + } + +} + +@Path("/") +public interface GithubApi { + + @GET + @Path("/repos/{user}/{repo}") + Observable getRepository(@PathParam("user") String username, @PathParam("repo") String repo); +} + +``` + +## Licence +[MIT](LICENCE.txt) \ No newline at end of file diff --git a/exampleSite/content/docs/dropwizard-configuration.md b/exampleSite/content/docs/dropwizard-configuration.md new file mode 100644 index 0000000..9bfdb70 --- /dev/null +++ b/exampleSite/content/docs/dropwizard-configuration.md @@ -0,0 +1,35 @@ +## Dropwizard configuration + +Use provided `RxJerseyBundle` +```java +@Override +public void initialize(Bootstrap bootstrap) { + bootstrap.addBundle(new RxJerseyBundle() + .setClientConfigurationProvider(config -> config.client) + .register(HeaderInterceptor.class) + ); +} +``` + +Alternatively you can directly configure and register Jersey feature +```java +public void run(RxJerseyConfiguration configuration, Environment environment) throws Exception { + JerseyEnvironment jersey = environment.jersey(); + + Client client = new JerseyClientBuilder(environment) + .using(configuration.client) + .using(new GrizzlyConnectorProvider()) + .buildRx("Client", RxObservableInvoker.class); + + RxJerseyServerFeature rxJerseyServerFeature = new RxJerseyServerFeature() + .register(HeaderInterceptor.class); + + RxJerseyClientFeature rxJerseyClientFeature = new RxJerseyClientFeature() + .register(client); + + jersey.register(rxJerseyServerFeature); + jersey.register(rxJerseyClientFeature); +} +``` + +#### [See example](https://github.com/alex-shpak/rx-jersey/tree/master/example) for more information \ No newline at end of file diff --git a/exampleSite/content/docs/jersey-configuration.md b/exampleSite/content/docs/jersey-configuration.md new file mode 100644 index 0000000..b5cd3c6 --- /dev/null +++ b/exampleSite/content/docs/jersey-configuration.md @@ -0,0 +1,20 @@ +## Jersey configuration +### Simple configuration +This will assume default configuration with no interceptor and Grizzly client +```java +resourceConfig.register(RxJerseyServerFeature.class); +resourceConfig.register(RxJerseyClientFeature.class); +``` + +### Detailed configuration +This configuration will add async request interceptor and override default client +```java +RxJerseyServerFeature rxJerseyServerFeature = new RxJerseyServerFeature() + .register(AuthRequestInterceptor.class); + +RxJerseyClientFeature rxJerseyClientFeature = new RxJerseyClientFeature() + .register(client); // Should be non-blocking client implementation + +resourceConfig.register(rxJerseyServerFeature); +resourceConfig.register(rxJerseyClientFeature); +``` \ No newline at end of file diff --git a/exampleSite/content/docs/rx-jersey-client.md b/exampleSite/content/docs/rx-jersey-client.md new file mode 100644 index 0000000..b0e2793 --- /dev/null +++ b/exampleSite/content/docs/rx-jersey-client.md @@ -0,0 +1,60 @@ +## RxJersey Proxy Client + +Proxy client provides convenient way to call resources without constructing request. Also it allows to reuse resource interfaces between microservices. + +In order to enable RxJava in proxy client register Jersey feature +```java +RxJerseyClientFeature rxJerseyClientFeature = new RxJerseyClientFeature() + .register(client); //should be non-blocking client implementation +resourceConfig.register(rxJerseyClientFeature); +``` +Default client with Grizzly connector will be used if not provided + + +## Remote resource injection +You can inject proxy client with `@Remote` annotation, in addition you can inject `WebTarget` or `RxWebTarget` +```java +@Path("/example/") +public class GithubResource { + + @Remote("https://api.github.com/") + private GithubApi githubApi; + + @Remote("https://api.github.com/") + private WebTarget webTarget; + + @GET + @Path("github") + public Single getRepository() { + return githubApi.getRepository("alex-shpak", "rx-jersey").toSingle(); + } +} +``` + +## Manual proxy client creation +You can use `WebResourceFactory` from `net.winterly.rxjersey.client` package in order to create proxy client + +#### RxJava +```java +WebResourceFactory.newResource( + ResourceInterface.class, + rxWebTarget, + new ObservableClientMethodInvoker() +); +``` +#### RxJava 2 +```java +WebResourceFactory.newResource( + ResourceInterface.class, + webTarget, + new FlowableClientMethodInvoker() +); +``` + +## Url resolving +Below is example of URL merging based on `@Remote` annotation value + +| Annotation Value | Jersey Context Path | Result URL | +| ----------------------------- | --------------------------- | ---------------------------- | +| @Remote("http://example.com") | http://baseurl.com/resource | http://example.com/ | +| @Remote("/resource/") | http://baseurl.com/some | http://baseurl.com/resource/ | \ No newline at end of file diff --git a/exampleSite/content/docs/rx-jersey-server.md b/exampleSite/content/docs/rx-jersey-server.md new file mode 100644 index 0000000..105e581 --- /dev/null +++ b/exampleSite/content/docs/rx-jersey-server.md @@ -0,0 +1,64 @@ +## Jersey Server +Register `RxJerseyServerFeature` in `resourceConfig` +```java +resourceConfig.register(RxJerseyServerFeature.class); +``` +Or with configuration +```java +RxJerseyServerFeature rxJerseyServerFeature = new RxJerseyServerFeature() + .register(AuthInterceptor.class); + +resourceConfig.register(rxJerseyServerFeature); +``` + +Update your resource adding rx return type: +```java +@Path("/") +public class HelloResource { + + @GET + public Single getAsync() { + return Single.just(new HelloEntity()); + } + + + public static class HelloEntity { + public String hello = "world"; + } +} +``` + +## Inteceptor +You can use RxJava enabled interceptors. Result of such interceptor will be ignored. Thrown or returned error would be redirected to jersey. + +#### RxJava +```java +public class SimpleInterceptor implements ObservableRequestInterceptor { + public Observable intercept(ContainerRequestContext requestContext) { + return Observable.empty(); + } +} +``` + +#### RxJava 2 +```java +public class SimpleInterceptor implements CompletableRequestInterceptor { + public Completable intercept(ContainerRequestContext requestContext) { + return Observable.complete(); + } +} +``` + + +## Important notes +#### RxJava + - It's recommended to use `rx.Single` as return type (Representing single response entity). + - Multiple elements emitted in `Observable` will be treated as error. + - Empty `Observable` or `null` value in `Observable` or `Single` will be treated as `204: No content`. + - `Completable` will be executed and `204: No content` will be returned. + +#### RxJava 2 + - It's recommended to use `io.reactivex.Maybe` which could be 0 or 1 item or an error. + - Multiple elements emitted in `Observable` or `Flowable` will be treated as error. + - Empty `Observable`/`Maybe` will be treated as `204: No content`. + - `Completable` will be executed and `204: No content` will be returned. diff --git a/exampleSite/content/menu/index.md b/exampleSite/content/menu/index.md new file mode 100644 index 0000000..9e7ab46 --- /dev/null +++ b/exampleSite/content/menu/index.md @@ -0,0 +1,12 @@ +--- +headless: true +--- + +- [**Introduction**](/) +- [Configuration](/docs/jersey-configuration) + - [Jersey configuration](/docs/jersey-configuration) + - [Dropwizard configuration](/docs/dropwizard-configuration) +- **Usage** +- [Server](/docs/rx-jersey-server) +- [Client](/docs/rx-jersey-client) +- Vert.x Integration \ No newline at end of file -- cgit v1.2.3