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
11 months ago
committed by
GitHub
11 changed files with 359 additions and 69 deletions
@ -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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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