Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Add explicit keep rules for RxJava `Result` types to prevent their generic information from being removed.
- Add `allowoptimization` flags for most kept types.
- Add `Invocation.annotationUrl` which returns the original URL from the method annotation.
- Support `QUERY` method.

**Changed**

Expand Down
12 changes: 11 additions & 1 deletion retrofit/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,31 @@ def addMultiReleaseSourceSet(int version) {
addMultiReleaseSourceSet(14)
addMultiReleaseSourceSet(16)

def extra = sourceSets.create('extra') {
java.srcDir('src/main/extra')
}

dependencies {
api libs.okhttp.client
api extra.output

compileOnly libs.android
compileOnly libs.kotlinx.coroutines

compileOnly libs.animalSnifferAnnotations
compileOnly libs.findBugsAnnotations

// Can't extend extraCompileOnly from compileOnly due to the circular dependencies.
extraCompileOnly libs.okhttp.client
}

javadoc {
exclude('retrofit2/internal/**')
}

jar {
tasks.named('jar', Jar) {
from(extra.output)

manifest {
attributes 'Automatic-Module-Name': 'retrofit2'
attributes 'Multi-Release': 'true'
Expand Down
17 changes: 17 additions & 0 deletions retrofit/java-test/src/test/java/retrofit2/RequestFactoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Path;
import retrofit2.http.QUERY;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
import retrofit2.http.QueryName;
Expand Down Expand Up @@ -1005,6 +1006,22 @@ Call<ResponseBody> method() {
assertThat(request.body()).isNull();
}

@Test
public void query() {
class Example {
@QUERY("/foo/bar/") //
Call<ResponseBody> method(@Body RequestBody body) {
return null;
}
}
RequestBody body = RequestBody.create(TEXT_PLAIN, "hi");
Request request = buildRequest(Example.class, body);
assertThat(request.method()).isEqualTo("QUERY");
assertThat(request.headers().size()).isEqualTo(0);
assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/");
assertBody(request.body(), "hi");
}

@Test
public void getWithPathParam() {
class Example {
Expand Down
39 changes: 39 additions & 0 deletions retrofit/src/main/extra/retrofit2/http/QUERY.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2025 Square, 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 retrofit2.http;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import okhttp3.HttpUrl;

/** Make a QUERY request. */
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface QUERY {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
*
* <p>See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
3 changes: 3 additions & 0 deletions retrofit/src/main/java/retrofit2/RequestFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Path;
import retrofit2.http.QUERY;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
import retrofit2.http.QueryName;
Expand Down Expand Up @@ -244,6 +245,8 @@ private void parseMethodAnnotation(Annotation annotation) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof QUERY) {
parseHttpMethodAndPath("QUERY", ((QUERY) annotation).value(), true);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
Expand Down
5 changes: 3 additions & 2 deletions retrofit/src/main/java/retrofit2/Retrofit.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ public final class Retrofit {
* <p>The relative path for a given method is obtained from an annotation on the method describing
* the request type. The built-in methods are {@link retrofit2.http.GET GET}, {@link
* retrofit2.http.PUT PUT}, {@link retrofit2.http.POST POST}, {@link retrofit2.http.PATCH PATCH},
* {@link retrofit2.http.HEAD HEAD}, {@link retrofit2.http.DELETE DELETE} and {@link
* retrofit2.http.OPTIONS OPTIONS}. You can use a custom HTTP method with {@link HTTP @HTTP}. For
* {@link retrofit2.http.HEAD HEAD}, {@link retrofit2.http.DELETE DELETE},
* {@link retrofit2.http.OPTIONS OPTIONS}, and {@link retrofit2.http.QUERY QUERY}.
* You can use a custom HTTP method with {@link HTTP @HTTP}. For
* a dynamic URL, omit the path on the annotation and annotate the first parameter with {@link
* Url @Url}.
*
Expand Down
Loading