001/*
002 * Copyright 2002-2016 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.client;
018
019import java.net.URI;
020import java.util.Map;
021import java.util.Set;
022import java.util.concurrent.Future;
023
024import org.springframework.core.ParameterizedTypeReference;
025import org.springframework.http.HttpEntity;
026import org.springframework.http.HttpHeaders;
027import org.springframework.http.HttpMethod;
028import org.springframework.http.ResponseEntity;
029import org.springframework.util.concurrent.ListenableFuture;
030
031/**
032 * Interface specifying a basic set of asynchronous RESTful operations.
033 * Implemented by {@link AsyncRestTemplate}. Not often used directly, but a useful
034 * option to enhance testability, as it can easily be mocked or stubbed.
035 *
036 * @author Arjen Poutsma
037 * @since 4.0
038 * @see AsyncRestTemplate
039 * @see RestOperations
040 */
041public interface AsyncRestOperations {
042
043        /**
044         * Expose the synchronous Spring RestTemplate to allow synchronous invocation.
045         */
046        RestOperations getRestOperations();
047
048
049        // GET
050
051        /**
052         * Asynchronously retrieve an entity by doing a GET on the specified URL.
053         * The response is converted and stored in an {@link ResponseEntity}.
054         * <p>URI Template variables are expanded using the given URI variables, if any.
055         * @param url the URL
056         * @param responseType the type of the return value
057         * @param uriVariables the variables to expand the template
058         * @return the entity wrapped in a {@link Future}
059         */
060        <T> ListenableFuture<ResponseEntity<T>> getForEntity(String url, Class<T> responseType,
061                        Object... uriVariables) throws RestClientException;
062
063        /**
064         * Asynchronously retrieve a representation by doing a GET on the URI template.
065         * The response is converted and stored in an {@link ResponseEntity}.
066         * <p>URI Template variables are expanded using the given map.
067         * @param url the URL
068         * @param responseType the type of the return value
069         * @param uriVariables the map containing variables for the URI template
070         * @return the entity wrapped in a {@link Future}
071         */
072        <T> ListenableFuture<ResponseEntity<T>> getForEntity(String url, Class<T> responseType,
073                        Map<String, ?> uriVariables) throws RestClientException;
074
075        /**
076         * Asynchronously retrieve a representation by doing a GET on the URL.
077         * The response is converted and stored in an {@link ResponseEntity}.
078         * @param url the URL
079         * @param responseType the type of the return value
080         * @return the entity wrapped in a {@link Future}
081         */
082        <T> ListenableFuture<ResponseEntity<T>> getForEntity(URI url, Class<T> responseType)
083                        throws RestClientException;
084
085
086        // HEAD
087
088        /**
089         * Asynchronously retrieve all headers of the resource specified by the URI template.
090         * <p>URI Template variables are expanded using the given URI variables, if any.
091         * @param url the URL
092         * @param uriVariables the variables to expand the template
093         * @return all HTTP headers of that resource wrapped in a {@link Future}
094         */
095        ListenableFuture<HttpHeaders> headForHeaders(String url, Object... uriVariables)
096                        throws RestClientException;
097
098        /**
099         * Asynchronously retrieve all headers of the resource specified by the URI template.
100         * <p>URI Template variables are expanded using the given map.
101         * @param url the URL
102         * @param uriVariables the map containing variables for the URI template
103         * @return all HTTP headers of that resource wrapped in a {@link Future}
104         */
105        ListenableFuture<HttpHeaders> headForHeaders(String url, Map<String, ?> uriVariables)
106                        throws RestClientException;
107
108        /**
109         * Asynchronously retrieve all headers of the resource specified by the URL.
110         * @param url the URL
111         * @return all HTTP headers of that resource wrapped in a {@link Future}
112         */
113        ListenableFuture<HttpHeaders> headForHeaders(URI url) throws RestClientException;
114
115
116        // POST
117
118        /**
119         * Create a new resource by POSTing the given object to the URI template, and
120         * asynchronously returns the value of the {@code Location} header. This header
121         * typically indicates where the new resource is stored.
122         * <p>URI Template variables are expanded using the given URI variables, if any.
123         * @param url the URL
124         * @param request the Object to be POSTed (may be {@code null})
125         * @param uriVariables the variables to expand the template
126         * @return the value for the {@code Location} header wrapped in a {@link Future}
127         * @see org.springframework.http.HttpEntity
128         */
129        ListenableFuture<URI> postForLocation(String url, HttpEntity<?> request, Object... uriVariables)
130                        throws RestClientException;
131
132        /**
133         * Create a new resource by POSTing the given object to the URI template, and
134         * asynchronously returns the value of the {@code Location} header. This header
135         * typically indicates where the new resource is stored.
136         * <p>URI Template variables are expanded using the given map.
137         * @param url the URL
138         * @param request the Object to be POSTed (may be {@code null})
139         * @param uriVariables the variables to expand the template
140         * @return the value for the {@code Location} header wrapped in a {@link Future}
141         * @see org.springframework.http.HttpEntity
142         */
143        ListenableFuture<URI> postForLocation(String url, HttpEntity<?> request, Map<String, ?> uriVariables)
144                        throws RestClientException;
145
146        /**
147         * Create a new resource by POSTing the given object to the URL, and asynchronously
148         * returns the value of the {@code Location} header. This header typically indicates
149         * where the new resource is stored.
150         * @param url the URL
151         * @param request the Object to be POSTed (may be {@code null})
152         * @return the value for the {@code Location} header wrapped in a {@link Future}
153         * @see org.springframework.http.HttpEntity
154         */
155        ListenableFuture<URI> postForLocation(URI url, HttpEntity<?> request) throws RestClientException;
156
157        /**
158         * Create a new resource by POSTing the given object to the URI template,
159         * and asynchronously returns the response as {@link ResponseEntity}.
160         * <p>URI Template variables are expanded using the given URI variables, if any.
161         * @param url the URL
162         * @param request the Object to be POSTed (may be {@code null})
163         * @param uriVariables the variables to expand the template
164         * @return the entity wrapped in a {@link Future}
165         * @see org.springframework.http.HttpEntity
166         */
167        <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request,
168                        Class<T> responseType, Object... uriVariables) throws RestClientException;
169
170        /**
171         * Create a new resource by POSTing the given object to the URI template,
172         * and asynchronously returns the response as {@link ResponseEntity}.
173         * <p>URI Template variables are expanded using the given map.
174         * @param url the URL
175         * @param request the Object to be POSTed (may be {@code null})
176         * @param uriVariables the variables to expand the template
177         * @return the entity wrapped in a {@link Future}
178         * @see org.springframework.http.HttpEntity
179         */
180        <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request,
181                        Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
182
183        /**
184         * Create a new resource by POSTing the given object to the URL,
185         * and asynchronously returns the response as {@link ResponseEntity}.
186         * @param url the URL
187         * @param request the Object to be POSTed (may be {@code null})
188         * @return the entity wrapped in a {@link Future}
189         * @see org.springframework.http.HttpEntity
190         */
191        <T> ListenableFuture<ResponseEntity<T>> postForEntity(URI url, HttpEntity<?> request,
192                        Class<T> responseType) throws RestClientException;
193
194
195        // PUT
196
197        /**
198         * Create or update a resource by PUTting the given object to the URI.
199         * <p>URI Template variables are expanded using the given URI variables, if any.
200         * <p>The Future will return a {@code null} result upon completion.
201         * @param url the URL
202         * @param request the Object to be PUT (may be {@code null})
203         * @param uriVariables the variables to expand the template
204         * @see HttpEntity
205         */
206        ListenableFuture<?> put(String url, HttpEntity<?> request, Object... uriVariables)
207                        throws RestClientException;
208
209        /**
210         * Creates a new resource by PUTting the given object to URI template.
211         * <p>URI Template variables are expanded using the given map.
212         * <p>The Future will return a {@code null} result upon completion.
213         * @param url the URL
214         * @param request the Object to be PUT (may be {@code null})
215         * @param uriVariables the variables to expand the template
216         * @see HttpEntity
217         */
218        ListenableFuture<?> put(String url, HttpEntity<?> request, Map<String, ?> uriVariables)
219                        throws RestClientException;
220
221        /**
222         * Creates a new resource by PUTting the given object to URL.
223         * <p>The Future will return a {@code null} result upon completion.
224         * @param url the URL
225         * @param request the Object to be PUT (may be {@code null})
226         * @see HttpEntity
227         */
228        ListenableFuture<?> put(URI url, HttpEntity<?> request) throws RestClientException;
229
230
231        // DELETE
232
233        /**
234         * Asynchronously delete the resources at the specified URI.
235         * <p>URI Template variables are expanded using the given URI variables, if any.
236         * <p>The Future will return a {@code null} result upon completion.
237         * @param url the URL
238         * @param uriVariables the variables to expand in the template
239         */
240        ListenableFuture<?> delete(String url, Object... uriVariables) throws RestClientException;
241
242        /**
243         * Asynchronously delete the resources at the specified URI.
244         * <p>URI Template variables are expanded using the given URI variables, if any.
245         * <p>The Future will return a {@code null} result upon completion.
246         * @param url the URL
247         * @param uriVariables the variables to expand in the template
248         */
249        ListenableFuture<?> delete(String url, Map<String, ?> uriVariables) throws RestClientException;
250
251        /**
252         * Asynchronously delete the resources at the specified URI.
253         * <p>URI Template variables are expanded using the given URI variables, if any.
254         * <p>The Future will return a {@code null} result upon completion.
255         * @param url the URL
256         */
257        ListenableFuture<?> delete(URI url) throws RestClientException;
258
259
260        // OPTIONS
261
262        /**
263         * Asynchronously return the value of the Allow header for the given URI.
264         * <p>URI Template variables are expanded using the given URI variables, if any.
265         * @param url the URL
266         * @param uriVariables the variables to expand in the template
267         * @return the value of the allow header wrapped in a {@link Future}
268         */
269        ListenableFuture<Set<HttpMethod>> optionsForAllow(String url, Object... uriVariables)
270                        throws RestClientException;
271
272        /**
273         * Asynchronously return the value of the Allow header for the given URI.
274         * <p>URI Template variables are expanded using the given map.
275         * @param url the URL
276         * @param uriVariables the variables to expand in the template
277         * @return the value of the allow header wrapped in a {@link Future}
278         */
279        ListenableFuture<Set<HttpMethod>> optionsForAllow(String url, Map<String, ?> uriVariables)
280                        throws RestClientException;
281
282        /**
283         * Asynchronously return the value of the Allow header for the given URL.
284         * @param url the URL
285         * @return the value of the allow header wrapped in a {@link Future}
286         */
287        ListenableFuture<Set<HttpMethod>> optionsForAllow(URI url) throws RestClientException;
288
289
290        // exchange
291
292        /**
293         * Asynchronously execute the HTTP method to the given URI template, writing the
294         * given request entity to the request, and returns the response as
295         * {@link ResponseEntity}.
296         * <p>URI Template variables are expanded using the given URI variables, if any.
297         * @param url the URL
298         * @param method the HTTP method (GET, POST, etc)
299         * @param requestEntity the entity (headers and/or body) to write to the request
300         * (may be {@code null})
301         * @param responseType the type of the return value
302         * @param uriVariables the variables to expand in the template
303         * @return the response as entity wrapped in a {@link Future}
304         */
305        <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method,
306                        HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
307                        throws RestClientException;
308
309        /**
310         * Asynchronously execute the HTTP method to the given URI template, writing the
311         * given request entity to the request, and returns the response as
312         * {@link ResponseEntity}.
313         * <p>URI Template variables are expanded using the given URI variables, if any.
314         * @param url the URL
315         * @param method the HTTP method (GET, POST, etc)
316         * @param requestEntity the entity (headers and/or body) to write to the request
317         * (may be {@code null})
318         * @param responseType the type of the return value
319         * @param uriVariables the variables to expand in the template
320         * @return the response as entity wrapped in a {@link Future}
321         */
322        <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method,
323                        HttpEntity<?> requestEntity, Class<T> responseType,
324                        Map<String, ?> uriVariables) throws RestClientException;
325
326        /**
327         * Asynchronously execute the HTTP method to the given URI template, writing the
328         * given request entity to the request, and returns the response as
329         * {@link ResponseEntity}.
330         * @param url the URL
331         * @param method the HTTP method (GET, POST, etc)
332         * @param requestEntity the entity (headers and/or body) to write to the request
333         * (may be {@code null})
334         * @param responseType the type of the return value
335         * @return the response as entity wrapped in a {@link Future}
336         */
337        <T> ListenableFuture<ResponseEntity<T>> exchange(URI url, HttpMethod method,
338                        HttpEntity<?> requestEntity, Class<T> responseType)
339                        throws RestClientException;
340
341        /**
342         * Asynchronously execute the HTTP method to the given URI template, writing the given
343         * request entity to the request, and returns the response as {@link ResponseEntity}.
344         * The given {@link ParameterizedTypeReference} is used to pass generic type
345         * information:
346         * <pre class="code">
347         * ParameterizedTypeReference&lt;List&lt;MyBean&gt;&gt; myBean = new ParameterizedTypeReference&lt;List&lt;MyBean&gt;&gt;() {};
348         * ResponseEntity&lt;List&lt;MyBean&gt;&gt; response = template.exchange(&quot;https://example.com&quot;,HttpMethod.GET, null, myBean);
349         * </pre>
350         * @param url the URL
351         * @param method the HTTP method (GET, POST, etc)
352         * @param requestEntity the entity (headers and/or body) to write to the
353         * request (may be {@code null})
354         * @param responseType the type of the return value
355         * @param uriVariables the variables to expand in the template
356         * @return the response as entity wrapped in a {@link Future}
357         */
358        <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method,
359                        HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType,
360                        Object... uriVariables) throws RestClientException;
361
362        /**
363         * Asynchronously execute the HTTP method to the given URI template, writing the given
364         * request entity to the request, and returns the response as {@link ResponseEntity}.
365         * The given {@link ParameterizedTypeReference} is used to pass generic type
366         * information:
367         * <pre class="code">
368         * ParameterizedTypeReference&lt;List&lt;MyBean&gt;&gt; myBean = new ParameterizedTypeReference&lt;List&lt;MyBean&gt;&gt;() {};
369         * ResponseEntity&lt;List&lt;MyBean&gt;&gt; response = template.exchange(&quot;https://example.com&quot;,HttpMethod.GET, null, myBean);
370         * </pre>
371         * @param url the URL
372         * @param method the HTTP method (GET, POST, etc)
373         * @param requestEntity the entity (headers and/or body) to write to the request
374         * (may be {@code null})
375         * @param responseType the type of the return value
376         * @param uriVariables the variables to expand in the template
377         * @return the response as entity wrapped in a {@link Future}
378         */
379        <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method,
380                        HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType,
381                        Map<String, ?> uriVariables) throws RestClientException;
382
383        /**
384         * Asynchronously execute the HTTP method to the given URI template, writing the given
385         * request entity to the request, and returns the response as {@link ResponseEntity}.
386         * The given {@link ParameterizedTypeReference} is used to pass generic type
387         * information:
388         * <pre class="code">
389         * ParameterizedTypeReference&lt;List&lt;MyBean&gt;&gt; myBean = new ParameterizedTypeReference&lt;List&lt;MyBean&gt;&gt;() {};
390         * ResponseEntity&lt;List&lt;MyBean&gt;&gt; response = template.exchange(&quot;https://example.com&quot;,HttpMethod.GET, null, myBean);
391         * </pre>
392         * @param url the URL
393         * @param method the HTTP method (GET, POST, etc)
394         * @param requestEntity the entity (headers and/or body) to write to the request
395         * (may be {@code null})
396         * @param responseType the type of the return value
397         * @return the response as entity wrapped in a {@link Future}
398         */
399        <T> ListenableFuture<ResponseEntity<T>> exchange(URI url, HttpMethod method,
400                        HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
401                        throws RestClientException;
402
403
404        // general execution
405
406        /**
407         * Asynchronously execute the HTTP method to the given URI template, preparing the
408         * request with the {@link AsyncRequestCallback}, and reading the response with a
409         * {@link ResponseExtractor}.
410         * <p>URI Template variables are expanded using the given URI variables, if any.
411         * @param url the URL
412         * @param method the HTTP method (GET, POST, etc)
413         * @param requestCallback object that prepares the request
414         * @param responseExtractor object that extracts the return value from the response
415         * @param uriVariables the variables to expand in the template
416         * @return an arbitrary object, as returned by the {@link ResponseExtractor}
417         */
418        <T> ListenableFuture<T> execute(String url, HttpMethod method,
419                        AsyncRequestCallback requestCallback, ResponseExtractor<T> responseExtractor,
420                        Object... uriVariables) throws RestClientException;
421
422        /**
423         * Asynchronously execute the HTTP method to the given URI template, preparing the
424         * request with the {@link AsyncRequestCallback}, and reading the response with a
425         * {@link ResponseExtractor}.
426         * <p>URI Template variables are expanded using the given URI variables map.
427         * @param url the URL
428         * @param method the HTTP method (GET, POST, etc)
429         * @param requestCallback object that prepares the request
430         * @param responseExtractor object that extracts the return value from the response
431         * @param uriVariables the variables to expand in the template
432         * @return an arbitrary object, as returned by the {@link ResponseExtractor}
433         */
434        <T> ListenableFuture<T> execute(String url, HttpMethod method,
435                        AsyncRequestCallback requestCallback, ResponseExtractor<T> responseExtractor,
436                        Map<String, ?> uriVariables) throws RestClientException;
437
438        /**
439         * Asynchronously execute the HTTP method to the given URL, preparing the request
440         * with the {@link AsyncRequestCallback}, and reading the response with a
441         * {@link ResponseExtractor}.
442         * @param url the URL
443         * @param method the HTTP method (GET, POST, etc)
444         * @param requestCallback object that prepares the request
445         * @param responseExtractor object that extracts the return value from the response
446         * @return an arbitrary object, as returned by the {@link ResponseExtractor}
447         */
448        <T> ListenableFuture<T> execute(URI url, HttpMethod method,
449                        AsyncRequestCallback requestCallback, ResponseExtractor<T> responseExtractor)
450                        throws RestClientException;
451
452}