
feign.Feign Maven / Gradle / Ivy
/*
* Copyright 2013 Netflix, Inc.
*
* 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;
import feign.Logger.NoOpLogger;
import feign.ReflectiveFeign.ParseHandlersByName;
import feign.Request.Options;
import feign.Target.HardCodedTarget;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.codec.ErrorDecoder;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Feign's purpose is to ease development against http apis that feign
* restfulness.
*
* In implementation, Feign is a {@link Feign#newInstance factory} for
* generating {@link Target targeted} http apis.
*/
public abstract class Feign {
/**
* Returns a new instance of an HTTP API, defined by annotations in the
* {@link Feign Contract}, for the specified {@code target}. You should
* cache this result.
*/
public abstract T newInstance(Target target);
public static Builder builder() {
return new Builder();
}
/**
*
* Configuration keys are formatted as unresolved see tags.
*
* For example.
*
* - {@code Route53}: would match a class such as
* {@code denominator.route53.Route53}
*
- {@code Route53#list()}: would match a method such as
* {@code denominator.route53.Route53#list()}
*
- {@code Route53#listAt(Marker)}: would match a method such as
* {@code denominator.route53.Route53#listAt(denominator.route53.Marker)}
*
- {@code Route53#listByNameAndType(String, String)}: would match a
* method such as {@code denominator.route53.Route53#listAt(String, String)}
*
*
* Note that there is no whitespace expected in a key!
*/
public static String configKey(Method method) {
StringBuilder builder = new StringBuilder();
builder.append(method.getDeclaringClass().getSimpleName());
builder.append('#').append(method.getName()).append('(');
for (Class> param : method.getParameterTypes())
builder.append(param.getSimpleName()).append(',');
if (method.getParameterTypes().length > 0)
builder.deleteCharAt(builder.length() - 1);
return builder.append(')').toString();
}
public static class Builder {
private final List requestInterceptors = new ArrayList();
private Logger.Level logLevel = Logger.Level.NONE;
private Contract contract = new Contract.Default();
private Client client = new Client.Default(null, null);
private Retryer retryer = new Retryer.Default();
private Logger logger = new NoOpLogger();
private Encoder encoder = new Encoder.Default();
private Decoder decoder = new Decoder.Default();
private ErrorDecoder errorDecoder = new ErrorDecoder.Default();
private Options options = new Options();
private InvocationHandlerFactory invocationHandlerFactory = new InvocationHandlerFactory.Default();
public Builder logLevel(Logger.Level logLevel) {
this.logLevel = logLevel;
return this;
}
public Builder contract(Contract contract) {
this.contract = contract;
return this;
}
public Builder client(Client client) {
this.client = client;
return this;
}
public Builder retryer(Retryer retryer) {
this.retryer = retryer;
return this;
}
public Builder logger(Logger logger) {
this.logger = logger;
return this;
}
public Builder encoder(Encoder encoder) {
this.encoder = encoder;
return this;
}
public Builder decoder(Decoder decoder) {
this.decoder = decoder;
return this;
}
public Builder errorDecoder(ErrorDecoder errorDecoder) {
this.errorDecoder = errorDecoder;
return this;
}
public Builder options(Options options) {
this.options = options;
return this;
}
/**
* Adds a single request interceptor to the builder.
*/
public Builder requestInterceptor(RequestInterceptor requestInterceptor) {
this.requestInterceptors.add(requestInterceptor);
return this;
}
/**
* Sets the full set of request interceptors for the builder, overwriting any previous interceptors.
*/
public Builder requestInterceptors(Iterable requestInterceptors) {
this.requestInterceptors.clear();
for (RequestInterceptor requestInterceptor : requestInterceptors) {
this.requestInterceptors.add(requestInterceptor);
}
return this;
}
/** Allows you to override how reflective dispatch works inside of Feign. */
public Builder invocationHandlerFactory(InvocationHandlerFactory invocationHandlerFactory) {
this.invocationHandlerFactory = invocationHandlerFactory;
return this;
}
public T target(Class apiType, String url) {
return target(new HardCodedTarget(apiType, url));
}
public T target(Target target) {
return build().newInstance(target);
}
public Feign build() {
SynchronousMethodHandler.Factory synchronousMethodHandlerFactory =
new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger, logLevel);
ParseHandlersByName handlersByName = new ParseHandlersByName( contract, options, encoder, decoder,
errorDecoder, synchronousMethodHandlerFactory);
return new ReflectiveFeign(handlersByName, invocationHandlerFactory);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy