RoutingFunction.java 3.2 KB
Newer Older
A
Arjen Poutsma 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
/*
 * Copyright 2002-2016 the original author or 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 org.springframework.web.reactive.function;

import java.util.Optional;

/**
 * Represents a function that routes to a {@linkplain HandlerFunction handler function}.
 *
 * @param <T> the type of the {@linkplain HandlerFunction handler function} to route to
 * @author Arjen Poutsma
 * @since 5.0
 */
@FunctionalInterface
public interface RoutingFunction<T> {

	/**
	 * Return the {@linkplain HandlerFunction handler function} that matches the given request.
	 * @param request the request to route to
	 * @return an {@code Optional} describing the {@code HandlerFunction} that matches this request,
	 * or an empty {@code Optional} if there is no match
	 */
	Optional<HandlerFunction<T>> route(Request request);

	/**
	 * Return a composed routing function that first invokes this function,
41
	 * and then invokes the {@code other} function (of the same type {@code T}) if this route had
A
Arjen Poutsma 已提交
42 43
	 * {@linkplain Optional#empty() no result}.
	 *
44
	 * @param other the function of type {@code T} to apply when this function has no result
A
Arjen Poutsma 已提交
45 46 47
	 * @return a composed function that first routes with this function and then the {@code other} function if this
	 * function has no result
	 */
48
	default RoutingFunction<T> andSame(RoutingFunction<T> other) {
A
Arjen Poutsma 已提交
49 50 51 52 53 54 55 56
		return request -> {
			Optional<HandlerFunction<T>> result = this.route(request);
			return result.isPresent() ? result : other.route(request);
		};
	}

	/**
	 * Return a composed routing function that first invokes this function,
57
	 * and then invokes the {@code other} function (of a different type) if this route had
A
Arjen Poutsma 已提交
58 59 60 61 62 63
	 * {@linkplain Optional#empty() no result}.
	 *
	 * @param other the function to apply when this function has no result
	 * @return a composed function that first routes with this function and then the {@code other} function if this
	 * function has no result
	 */
64
	default RoutingFunction<?> and(RoutingFunction<?> other) {
A
Arjen Poutsma 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
		return request -> {
			Optional<HandlerFunction<Object>> result = this.route(request).
					map(CastingUtils::cast);
			return result.isPresent() ? result : other.route(request)
					.map(CastingUtils::cast);
		};
	}

	/**
	 * Filter all {@linkplain HandlerFunction handler functions} routed by this function with the given
	 * {@linkplain FilterFunction filter function}.
	 *
	 * @param filterFunction the filter to apply
	 * @param <S>            the filter return type
	 * @return the filtered routing function
	 */
	default <S> RoutingFunction<S> filter(FilterFunction<T, S> filterFunction) {
		return request -> this.route(request)
				.map(handlerFunction -> filterRequest -> filterFunction.filter(filterRequest, handlerFunction));
	}

}