Browse Source
* Refactoring: Move resolveLastTypeParameter from Util to Types * Add ReactiveDecoder * Update code as per suggestions * Update code as per suggestions * Refactoring * Add testspull/2204/head
Sergei Korneev
1 year ago
committed by
GitHub
11 changed files with 359 additions and 69 deletions
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
/* |
||||
* Copyright 2012-2023 The Feign Authors |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
||||
* in compliance with the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License |
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
||||
* or implied. See the License for the specific language governing permissions and limitations under |
||||
* the License. |
||||
*/ |
||||
package feign.reactive; |
||||
|
||||
import feign.FeignException; |
||||
import feign.Response; |
||||
import feign.Types; |
||||
import feign.codec.Decoder; |
||||
import reactor.core.publisher.Flux; |
||||
import reactor.core.publisher.Mono; |
||||
|
||||
import java.io.IOException; |
||||
import java.lang.reflect.Type; |
||||
import java.util.List; |
||||
|
||||
public class ReactorDecoder implements Decoder { |
||||
|
||||
private final Decoder delegate; |
||||
|
||||
public ReactorDecoder(Decoder decoder) { |
||||
this.delegate = decoder; |
||||
} |
||||
|
||||
@Override |
||||
public Object decode(Response response, Type type) throws IOException, FeignException { |
||||
Class<?> rawType = Types.getRawType(type); |
||||
if (rawType.isAssignableFrom(Mono.class)) { |
||||
Type lastType = Types.resolveLastTypeParameter(type, Mono.class); |
||||
return delegate.decode(response, lastType); |
||||
} |
||||
if (rawType.isAssignableFrom(Flux.class)) { |
||||
Type lastType = Types.resolveLastTypeParameter(type, Flux.class); |
||||
Type listType = Types.parameterize(List.class, lastType); |
||||
return delegate.decode(response, listType); |
||||
} |
||||
|
||||
return delegate.decode(response, type); |
||||
} |
||||
} |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
/* |
||||
* Copyright 2012-2023 The Feign Authors |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
||||
* in compliance with the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License |
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
||||
* or implied. See the License for the specific language governing permissions and limitations under |
||||
* the License. |
||||
*/ |
||||
package feign.reactive; |
||||
|
||||
import feign.FeignException; |
||||
import feign.Response; |
||||
import feign.Types; |
||||
import feign.codec.Decoder; |
||||
import io.reactivex.Flowable; |
||||
|
||||
import java.io.IOException; |
||||
import java.lang.reflect.Type; |
||||
|
||||
public class RxJavaDecoder implements Decoder { |
||||
|
||||
private final Decoder delegate; |
||||
|
||||
public RxJavaDecoder(Decoder decoder) { |
||||
this.delegate = decoder; |
||||
} |
||||
|
||||
@Override |
||||
public Object decode(Response response, Type type) throws IOException, FeignException { |
||||
Class<?> rawType = Types.getRawType(type); |
||||
if (rawType.isAssignableFrom(Flowable.class)) { |
||||
Type lastType = Types.resolveLastTypeParameter(type, Flowable.class); |
||||
return delegate.decode(response, lastType); |
||||
} |
||||
|
||||
return delegate.decode(response, type); |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
/* |
||||
* Copyright 2012-2023 The Feign Authors |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
||||
* in compliance with the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License |
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
||||
* or implied. See the License for the specific language governing permissions and limitations under |
||||
* the License. |
||||
*/ |
||||
package feign.reactive.examples; |
||||
|
||||
import feign.Logger; |
||||
|
||||
public class ConsoleLogger extends Logger { |
||||
@Override |
||||
protected void log(String configKey, String format, Object... args) { |
||||
System.out.println(String.format(methodTag(configKey) + format, args)); |
||||
} |
||||
} |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
/* |
||||
* Copyright 2012-2023 The Feign Authors |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
||||
* in compliance with the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License |
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
||||
* or implied. See the License for the specific language governing permissions and limitations under |
||||
* the License. |
||||
*/ |
||||
package feign.reactive.examples; |
||||
|
||||
import feign.Logger; |
||||
import feign.Param; |
||||
import feign.RequestLine; |
||||
import feign.jackson.JacksonDecoder; |
||||
import feign.reactive.ReactorDecoder; |
||||
import feign.reactive.ReactorFeign; |
||||
import reactor.core.publisher.Flux; |
||||
import reactor.core.publisher.Mono; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* adapted from {@code com.example.retrofit.GitHubClient} |
||||
*/ |
||||
public class ReactorGitHubExample { |
||||
|
||||
public static void main(String... args) { |
||||
GitHub github = ReactorFeign.builder() |
||||
.decoder(new ReactorDecoder(new JacksonDecoder())) |
||||
.logger(new ConsoleLogger()) |
||||
.logLevel(Logger.Level.FULL) |
||||
.target(GitHub.class, "https://api.github.com"); |
||||
|
||||
System.out.println("Let's fetch and print a list of the contributors to this library (Using Flux)."); |
||||
List<Contributor> contributorsFromFlux = github.contributorsFlux("OpenFeign", "feign") |
||||
.collectList() |
||||
.block(); |
||||
for (Contributor contributor : contributorsFromFlux) { |
||||
System.out.println(contributor.login + " (" + contributor.contributions + ")"); |
||||
} |
||||
|
||||
System.out.println("Let's fetch and print a list of the contributors to this library (Using Mono)."); |
||||
List<Contributor> contributorsFromMono = github.contributorsMono("OpenFeign", "feign") |
||||
.block(); |
||||
for (Contributor contributor : contributorsFromMono) { |
||||
System.out.println(contributor.login + " (" + contributor.contributions + ")"); |
||||
} |
||||
} |
||||
|
||||
interface GitHub { |
||||
@RequestLine("GET /repos/{owner}/{repo}/contributors") |
||||
Flux<Contributor> contributorsFlux(@Param("owner") String owner, @Param("repo") String repo); |
||||
|
||||
@RequestLine("GET /repos/{owner}/{repo}/contributors") |
||||
Mono<List<Contributor>> contributorsMono(@Param("owner") String owner, @Param("repo") String repo); |
||||
} |
||||
|
||||
static class Contributor { |
||||
|
||||
private String login; |
||||
private int contributions; |
||||
|
||||
void setLogin(String login) { |
||||
this.login = login; |
||||
} |
||||
|
||||
void setContributions(int contributions) { |
||||
this.contributions = contributions; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
/* |
||||
* Copyright 2012-2023 The Feign Authors |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
||||
* in compliance with the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License |
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
||||
* or implied. See the License for the specific language governing permissions and limitations under |
||||
* the License. |
||||
*/ |
||||
package feign.reactive.examples; |
||||
|
||||
import feign.Logger; |
||||
import feign.Param; |
||||
import feign.RequestLine; |
||||
import feign.jackson.JacksonDecoder; |
||||
import feign.reactive.RxJavaDecoder; |
||||
import feign.reactive.RxJavaFeign; |
||||
import io.reactivex.Flowable; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* adapted from {@code com.example.retrofit.GitHubClient} |
||||
*/ |
||||
public class RxJavaGitHubExample { |
||||
|
||||
public static void main(String... args) { |
||||
GitHub github = RxJavaFeign.builder() |
||||
.decoder(new RxJavaDecoder(new JacksonDecoder())) |
||||
.logger(new ConsoleLogger()) |
||||
.logLevel(Logger.Level.FULL) |
||||
.target(GitHub.class, "https://api.github.com"); |
||||
|
||||
System.out.println("Let's fetch and print a list of the contributors to this library."); |
||||
List<Contributor> contributorsFromFlux = github.contributors("OpenFeign", "feign") |
||||
.blockingLast(); |
||||
for (Contributor contributor : contributorsFromFlux) { |
||||
System.out.println(contributor.login + " (" + contributor.contributions + ")"); |
||||
} |
||||
|
||||
} |
||||
|
||||
interface GitHub { |
||||
@RequestLine("GET /repos/{owner}/{repo}/contributors") |
||||
Flowable<List<Contributor>> contributors(@Param("owner") String owner, @Param("repo") String repo); |
||||
} |
||||
|
||||
static class Contributor { |
||||
|
||||
private String login; |
||||
private int contributions; |
||||
|
||||
void setLogin(String login) { |
||||
this.login = login; |
||||
} |
||||
|
||||
void setContributions(int contributions) { |
||||
this.contributions = contributions; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue