From d04953bcff3d3222e7bb49a4cea2a17227188295 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sat, 5 Mar 2016 10:21:42 +0800 Subject: [PATCH] Adds HACKING file, to demystify change to Feign --- CONTRIBUTING.md | 3 ++- HACKING.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 20 ++++++++-------- 3 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 HACKING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3b26940..7b3d7a82 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,5 @@ # Contributing to Feign +Please read [HACKING](./HACKING.md] prior to raising change. If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request (on a branch other than `master` or `gh-pages`). @@ -6,7 +7,7 @@ When submitting code, please ensure you follow the [Google Style Guide](http://g ## License -By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/Netflix/Feign/blob/master/LICENSE +By contributing your code, you agree to license your contribution under the terms of the [APLv2](./LICENSE] All files are released with the Apache 2.0 license. diff --git a/HACKING.md b/HACKING.md new file mode 100644 index 00000000..cbe8d442 --- /dev/null +++ b/HACKING.md @@ -0,0 +1,62 @@ +# Hacking Feign +Feign is optimized for maintenance vs flexibility. It prefers small +features that have been asked for repeated times, that are insured with +tests, and have clear use cases. This limits the lines of code and count +of modules in Feign's repo. + +Code design is opinionated including below: + +* Classes and methods default to package, not public visibility. +* Changing certain implementation classes may be unsupported. +* 3rd-party dependencies, and gnarly apis like java.beans are avoided. + +## How to request change +The best way to approach something not yet supported is to ask on +[gitter](https://gitter.im/Netflix/feign) or [raise an issue](https://github.com/Netflix/feign/issues). +Asking for the feature you need (like how to deal with command groups) +vs a specific implementation (like making a private type public) will +give you more options to accomplish your goal. + +Advice usually comes in two parts: advice and workaround. Advice may be +to change Feign's code, or to fork until the feature is more widely +requested. + +## How change works +High quality pull requests that have clear scope and tests that reflect +the intent of the feature are often merged and released in days. If a +merged change isn't immediately released and it is of priority to you, +nag (make a comment) on your merged pull request until it is released. + +## How to experiment +Changes to Feign's code are best addressed by the feature requestor in a +pull request *after* discussing in an issue or on gitter. By discussing +first, there's less chance of a mutually disappointing experience where +a pull request is rejected. Moreover, the feature may be already present! + +Albeit rare, some features will be deferred or rejected for inclusion in +Feign's main repository. In these cases, the choices are typically to +either fork the repository, or make your own repository containing the +change. + +### Forks are welcome! +Forking isn't bad. It is a natural place to experiment and vet a feature +before it ends up in Feign's main repository. Large features or those +which haven't satisfied diverse need are often deferred to forks or +separate repositories (see [Rule of Three](http://blog.codinghorror.com/rule-of-three/)). + +### Large integrations -> separate repositories +If you look carefully, you'll notice Feign integrations are often less +than 1000 lines of code including tests. Some features are rejected for +inclusion solely due to the amount of maintenance. For example, adding +some features might imply tying up maintainers for several days or weeks +and resulting in a large percentage increase in the size of feign. + +Large integrations aren't bad, but to be sustainable, they need to be +isolated where the maintenance of that feature doesn't endanger the +maintainability of Feign itself. Feign has been going since 2012, without +the need of full-time attention. This is largely because maintenance is +low and approachable. + +A good example of a large integration is [spring-cloud-netflix](https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign). +Spring Cloud Netflix is sustainable as it has had several people +maintaining it, including Q&A support for years. diff --git a/README.md b/README.md index 5865f5e4..4fb381bd 100644 --- a/README.md +++ b/README.md @@ -63,13 +63,13 @@ CloudDNS cloudDNS = feign.target(new CloudIdentityTarget(user, apiKey) ``` ### Examples -Feign includes example [GitHub](https://github.com/Netflix/feign/tree/master/example-github) and [Wikipedia](https://github.com/Netflix/feign/tree/master/example-wikipedia) clients. The denominator project can also be scraped for Feign in practice. Particularly, look at its [example daemon](https://github.com/Netflix/denominator/tree/master/example-daemon). +Feign includes example [GitHub](./example-github) and [Wikipedia](./example-wikipedia) clients. The denominator project can also be scraped for Feign in practice. Particularly, look at its [example daemon](https://github.com/Netflix/denominator/tree/master/example-daemon). ### Integrations Feign intends to work well within Netflix and other Open Source communities. Modules are welcome to integrate with your favorite projects! ### Gson -[Gson](https://github.com/Netflix/feign/tree/master/gson) includes an encoder and decoder you can use with a JSON API. +[Gson](./gson) includes an encoder and decoder you can use with a JSON API. Add `GsonEncoder` and/or `GsonDecoder` to your `Feign.Builder` like so: @@ -82,7 +82,7 @@ GitHub github = Feign.builder() ``` ### Jackson -[Jackson](https://github.com/Netflix/feign/tree/master/jackson) includes an encoder and decoder you can use with a JSON API. +[Jackson](./jackson) includes an encoder and decoder you can use with a JSON API. Add `JacksonEncoder` and/or `JacksonDecoder` to your `Feign.Builder` like so: @@ -94,7 +94,7 @@ GitHub github = Feign.builder() ``` ### Sax -[SaxDecoder](https://github.com/Netflix/feign/tree/master/sax) allows you to decode XML in a way that is compatible with normal JVM and also Android environments. +[SaxDecoder](./sax) allows you to decode XML in a way that is compatible with normal JVM and also Android environments. Here's an example of how to configure Sax response parsing: ```java @@ -106,7 +106,7 @@ api = Feign.builder() ``` ### JAXB -[JAXB](https://github.com/Netflix/feign/tree/master/jaxb) includes an encoder and decoder you can use with an XML API. +[JAXB](./jaxb) includes an encoder and decoder you can use with an XML API. Add `JAXBEncoder` and/or `JAXBDecoder` to your `Feign.Builder` like so: @@ -118,7 +118,7 @@ api = Feign.builder() ``` ### JAX-RS -[JAXRSContract](https://github.com/Netflix/feign/tree/master/jaxrs) overrides annotation processing to instead use standard ones supplied by the JAX-RS specification. This is currently targeted at the 1.1 spec. +[JAXRSContract](./jaxrs) overrides annotation processing to instead use standard ones supplied by the JAX-RS specification. This is currently targeted at the 1.1 spec. Here's the example above re-written to use JAX-RS: ```java @@ -133,7 +133,7 @@ GitHub github = Feign.builder() .target(GitHub.class, "https://api.github.com"); ``` ### OkHttp -[OkHttpClient](https://github.com/Netflix/feign/tree/master/okhttp) directs Feign's http requests to [OkHttp](http://square.github.io/okhttp/), which enables SPDY and better network control. +[OkHttpClient](./okhttp) directs Feign's http requests to [OkHttp](http://square.github.io/okhttp/), which enables SPDY and better network control. To use OkHttp with Feign, add the OkHttp module to your classpath. Then, configure Feign to use the OkHttpClient: @@ -144,7 +144,7 @@ GitHub github = Feign.builder() ``` ### Ribbon -[RibbonClient](https://github.com/Netflix/feign/tree/master/ribbon) overrides URL resolution of Feign's client, adding smart routing and resiliency capabilities provided by [Ribbon](https://github.com/Netflix/ribbon). +[RibbonClient](./ribbon) overrides URL resolution of Feign's client, adding smart routing and resiliency capabilities provided by [Ribbon](https://github.com/Netflix/ribbon). Integration requires you to pass your ribbon client name as the host part of the url, for example `myAppProd`. ```java @@ -153,7 +153,7 @@ MyService api = Feign.builder().client(RibbonClient.create()).target(MyService.c ``` ### Hystrix -[HystrixFeign](https://github.com/Netflix/feign/tree/master/hystrix) configures circuit breaker support provided by [Hystrix](https://github.com/Netflix/Hystrix). +[HystrixFeign](./hystrix) configures circuit breaker support provided by [Hystrix](https://github.com/Netflix/Hystrix). To use Hystrix with Feign, add the Hystrix module to your classpath. Then use the `HystrixFeign` builder: @@ -163,7 +163,7 @@ MyService api = HystrixFeign.builder().target(MyService.class, "https://myAppPro ``` ### SLF4J -[SLF4JModule](https://github.com/Netflix/feign/tree/master/slf4j) allows directing Feign's logging to [SLF4J](http://www.slf4j.org/), allowing you to easily use a logging backend of your choice (Logback, Log4J, etc.) +[SLF4JModule](./slf4j) allows directing Feign's logging to [SLF4J](http://www.slf4j.org/), allowing you to easily use a logging backend of your choice (Logback, Log4J, etc.) To use SLF4J with Feign, add both the SLF4J module and an SLF4J binding of your choice to your classpath. Then, configure Feign to use the Slf4jLogger: