@@ -31,12 +31,14 @@ import reactor.core.publisher.Mono
31
31
import java.net.InetSocketAddress
32
32
import java.security.Principal
33
33
import kotlin.reflect.KClass
34
+ import kotlin.reflect.KType
35
+ import kotlin.reflect.full.starProjectedType
34
36
35
37
/* *
36
38
* Extension for [ServerRequest.bodyToMono] providing a `bodyToMono<Foo>()` variant
37
39
* leveraging Kotlin reified type parameters. This extension is not subject to type
38
40
* erasure and retains actual generic type arguments.
39
- *
41
+ *
40
42
* @author Sebastien Deleuze
41
43
* @since 5.0
42
44
*/
@@ -76,28 +78,73 @@ fun <T : Any> ServerRequest.bodyToFlow(clazz: KClass<T>): Flow<T> =
76
78
/* *
77
79
* Non-nullable Coroutines variant of [ServerRequest.bodyToMono].
78
80
*
81
+ * ### Deprecation
82
+ *
83
+ * This method is deprecated in favor of [awaitReceive].
84
+ *
85
+ * * It is difficult to reason about its exception handling,
86
+ * since it forces you to handle both types of errors: serialization and coroutines-related.
87
+ * * In the case of [IllegalArgumentException] it is indistinguishable if the exception came from coroutines
88
+ * or serialization unless checked explicit for `SerializationException` type.
89
+ * * It is unclear whether [IllegalArgumentException] can be thrown at all from coroutines-perspective
90
+ * as the receiver is a [Mono].
91
+ *
79
92
* @author Sebastien Deleuze
80
93
* @since 5.2
81
94
*/
95
+ @Deprecated(
96
+ message = " Deprecated in favor of awaitReceive." ,
97
+ level = DeprecationLevel .WARNING ,
98
+ replaceWith = ReplaceWith (" this.awaitReceive" )
99
+ )
82
100
suspend inline fun <reified T : Any > ServerRequest.awaitBody (): T =
83
101
bodyToMono<T >().awaitSingle()
84
102
85
103
/* *
86
104
* `KClass` non-nullable Coroutines variant of [ServerRequest.bodyToMono].
87
105
* Please consider `awaitBody<Foo>` variant if possible.
88
106
*
107
+ * ### Deprecation
108
+ *
109
+ * This method is deprecated in favor of [awaitReceive].
110
+ *
111
+ * * It is difficult to reason about its exception handling,
112
+ * since it forces you to handle both types of errors: serialization and coroutines-related.
113
+ * * In the case of [IllegalArgumentException] it is indistinguishable if the exception came from coroutines
114
+ * or serialization unless checked explicit for `SerializationException` type.
115
+ * * It is unclear whether [IllegalArgumentException] can be thrown at all from coroutines-perspective
116
+ * as the receiver is a [Mono].
117
+ *
89
118
* @author Igor Manushin
90
119
* @since 5.3
91
120
*/
121
+ @Deprecated(
122
+ message = " Deprecated in favor of awaitReceive." ,
123
+ level = DeprecationLevel .WARNING ,
124
+ replaceWith = ReplaceWith (" this.awaitReceive" )
125
+ )
92
126
suspend fun <T : Any > ServerRequest.awaitBody (clazz : KClass <T >): T =
93
127
bodyToMono(clazz.java).awaitSingle()
94
128
95
129
/* *
96
130
* Nullable Coroutines variant of [ServerRequest.bodyToMono].
97
131
*
132
+ * ### Deprecation
133
+ *
134
+ * This method is deprecated because the conventions established in Kotlin mandate that an operation
135
+ * with the name `awaitBodyOrNull` returns `null` instead of throwing in case there is an error;
136
+ * however, this would also mean that this method would return `null` if there is a serialization error.
137
+ * This can be confusing to those who expect this function to validate if incoming body can be transformed into expected `T`.
138
+ *
98
139
* @author Sebastien Deleuze
99
140
* @since 5.2
100
141
*/
142
+ @Deprecated(
143
+ message = " Deprecated without a replacement due to its name incorrectly conveying the behavior. " +
144
+ " Please consider replacing it with awaitReceiveOrNull." ,
145
+ level = DeprecationLevel .WARNING ,
146
+ replaceWith = ReplaceWith (" this.awaitReceiveOrNull" )
147
+ )
101
148
@Suppress(" DEPRECATION" )
102
149
suspend inline fun <reified T : Any > ServerRequest.awaitBodyOrNull (): T ? =
103
150
bodyToMono<T >().awaitSingleOrNull()
@@ -106,13 +153,61 @@ suspend inline fun <reified T : Any> ServerRequest.awaitBodyOrNull(): T? =
106
153
* `KClass` nullable Coroutines variant of [ServerRequest.bodyToMono].
107
154
* Please consider `awaitBodyOrNull<Foo>` variant if possible.
108
155
*
156
+ * ### Deprecation
157
+ *
158
+ * This method is deprecated because the conventions established in Kotlin mandate that an operation
159
+ * with the name `awaitBodyOrNull` returns `null` instead of throwing in case there is an error;
160
+ * however, this would also mean that this method would return `null` if there is a serialization error.
161
+ * This can be confusing to those who expect this function to validate if incoming body can be transformed into expected `T`.
162
+ *
109
163
* @author Igor Manushin
110
164
* @since 5.3
111
165
*/
166
+ @Deprecated(
167
+ message = " Deprecated without a replacement due to its name incorrectly conveying the behavior. " +
168
+ " Please consider replacing it with awaitReceiveOrNull." ,
169
+ level = DeprecationLevel .WARNING ,
170
+ replaceWith = ReplaceWith (" this.awaitReceiveOrNull" )
171
+ )
112
172
@Suppress(" DEPRECATION" )
113
173
suspend fun <T : Any > ServerRequest.awaitBodyOrNull (clazz : KClass <T >): T ? =
114
174
bodyToMono(clazz.java).awaitSingleOrNull()
115
175
176
+ /* *
177
+ * Receives the incoming body for this [request][ServerRequest] and transforms it to the requested `T` type.
178
+ *
179
+ * @author George Papadopoulos
180
+ * @since 6.0.11
181
+ * @throws IllegalArgumentException when body cannot be transformed to the requested type.
182
+ */
183
+ suspend inline fun <reified T : Any > ServerRequest.awaitReceive (): T = awaitReceiveNullable<T >()
184
+ ? : throw ContentTransformationException (starProjectedType<T >())
185
+
186
+ /* *
187
+ * Receives the incoming body for this [request][ServerRequest] and transforms it to the requested `T` type.
188
+ *
189
+ * @author George Papadopoulos
190
+ * @since 6.0.11
191
+ * @throws IllegalArgumentException when body cannot be transformed to the requested type.
192
+ */
193
+ suspend inline fun <reified T : Any > ServerRequest.awaitReceiveNullable (): T ? {
194
+ try {
195
+ return bodyToMono<T >().awaitSingleOrNull()
196
+ } catch (e: IllegalArgumentException ) {
197
+ throw ContentTransformationException (starProjectedType<T >())
198
+ }
199
+ }
200
+
201
+ @PublishedApi
202
+ internal class ContentTransformationException (
203
+ type : KType
204
+ ) : IllegalArgumentException(" Cannot transform this request's body to $type " )
205
+
206
+ @PublishedApi
207
+ internal inline fun <reified T : Any > starProjectedType (): KType {
208
+ return T ::class .starProjectedType
209
+ }
210
+
116
211
/* *
117
212
* Coroutines variant of [ServerRequest.formData].
118
213
*
0 commit comments