diff --git a/client/src/commonMain/kotlin/Client.kt b/client/src/commonMain/kotlin/Client.kt index fc3df8d..a43e6b6 100644 --- a/client/src/commonMain/kotlin/Client.kt +++ b/client/src/commonMain/kotlin/Client.kt @@ -10,6 +10,48 @@ import opensavvy.spine.api.FailureSpec import opensavvy.spine.api.Parameters import opensavvy.spine.api.ResolvedEndpoint +/** + * Invokes a [Ktor typesafe endpoint][ResolvedEndpoint]. + * + * If the following API has been declared: + * ```kotlin + * object Api : RootResource("v1") { + * object Users : StaticResource("users", Api) { + * val list by get() + * .response>() + * + * val create by post() + * .request() + * .response() + * + * object User : DynamicResource("user", Users) { + * val get by get() + * .response() + * } + * } + * } + * ``` + * + * An [HttpClient] can be used to call it: + * + * ```kotlin + * // List users: + * client.request(Api / Users / Users.list).bodyOrThrow() + * + * // Create a user: + * client.request(Api / Users / Users.create, UserCreation("John", 15)).bodyOrThrow() + * + * // Access a specific user: + * client.request(Api / Users / User("123456") / User.get).bodyOrThrow() + * ``` + * + * For this example to work, you will need to configure the [HttpClient]'s `DefaultRequest` and `ContentNegotiation` plugin. + * To do so, please follow [our tutorial](https://spine.opensavvy.dev/setup.html#client-side-implementation). + * + * @see bodyOrNull Access the body, returning `null` on failure. + * @see bodyOrThrow Access the body, throwing an exception on failure. + * @see handle Exhaustively handle declared failures. + */ suspend inline fun HttpClient.request( endpoint: ResolvedEndpoint>, input: In, @@ -36,6 +78,48 @@ suspend inline fun ("users", Api) { + * val list by get() + * .response>() + * + * val create by post() + * .request() + * .response() + * + * object User : DynamicResource("user", Users) { + * val get by get() + * .response() + * } + * } + * } + * ``` + * + * An [HttpClient] can be used to call it: + * + * ```kotlin + * // List users: + * client.request(Api / Users / Users.list).bodyOrThrow() + * + * // Create a user: + * client.request(Api / Users / Users.create, UserCreation("John", 15)).bodyOrThrow() + * + * // Access a specific user: + * client.request(Api / Users / User("123456") / User.get).bodyOrThrow() + * ``` + * + * For this example to work, you will need to configure the [HttpClient]'s `DefaultRequest` and `ContentNegotiation` plugin. + * To do so, please follow [our tutorial](https://spine.opensavvy.dev/setup.html#client-side-implementation). + * + * @see bodyOrNull Access the body, returning `null` on failure. + * @see bodyOrThrow Access the body, throwing an exception on failure. + * @see handle Exhaustively handle declared failures. + */ suspend inline fun HttpClient.request( endpoint: ResolvedEndpoint>, crossinline parameters: Params.() -> Unit, @@ -43,6 +127,48 @@ suspend inline fun Unit = {}, ): SpineResponse = request(endpoint, Unit, parameters, contentType, configure) +/** + * Invokes a [Ktor typesafe endpoint][ResolvedEndpoint]. + * + * If the following API has been declared: + * ```kotlin + * object Api : RootResource("v1") { + * object Users : StaticResource("users", Api) { + * val list by get() + * .response>() + * + * val create by post() + * .request() + * .response() + * + * object User : DynamicResource("user", Users) { + * val get by get() + * .response() + * } + * } + * } + * ``` + * + * An [HttpClient] can be used to call it: + * + * ```kotlin + * // List users: + * client.request(Api / Users / Users.list).bodyOrThrow() + * + * // Create a user: + * client.request(Api / Users / Users.create, UserCreation("John", 15)).bodyOrThrow() + * + * // Access a specific user: + * client.request(Api / Users / User("123456") / User.get).bodyOrThrow() + * ``` + * + * For this example to work, you will need to configure the [HttpClient]'s `DefaultRequest` and `ContentNegotiation` plugin. + * To do so, please follow [our tutorial](https://spine.opensavvy.dev/setup.html#client-side-implementation). + * + * @see bodyOrNull Access the body, returning `null` on failure. + * @see bodyOrThrow Access the body, throwing an exception on failure. + * @see handle Exhaustively handle declared failures. + */ suspend inline fun HttpClient.request( endpoint: ResolvedEndpoint>, input: In, @@ -50,6 +176,48 @@ suspend inline fun Unit = {}, ): SpineResponse = request(endpoint, input, {}, contentType, configure) +/** + * Invokes a [Ktor typesafe endpoint][ResolvedEndpoint]. + * + * If the following API has been declared: + * ```kotlin + * object Api : RootResource("v1") { + * object Users : StaticResource("users", Api) { + * val list by get() + * .response>() + * + * val create by post() + * .request() + * .response() + * + * object User : DynamicResource("user", Users) { + * val get by get() + * .response() + * } + * } + * } + * ``` + * + * An [HttpClient] can be used to call it: + * + * ```kotlin + * // List users: + * client.request(Api / Users / Users.list).bodyOrThrow() + * + * // Create a user: + * client.request(Api / Users / Users.create, UserCreation("John", 15)).bodyOrThrow() + * + * // Access a specific user: + * client.request(Api / Users / User("123456") / User.get).bodyOrThrow() + * ``` + * + * For this example to work, you will need to configure the [HttpClient]'s `DefaultRequest` and `ContentNegotiation` plugin. + * To do so, please follow [our tutorial](https://spine.opensavvy.dev/setup.html#client-side-implementation). + * + * @see bodyOrNull Access the body, returning `null` on failure. + * @see bodyOrThrow Access the body, throwing an exception on failure. + * @see handle Exhaustively handle declared failures. + */ suspend inline fun HttpClient.request( endpoint: ResolvedEndpoint>, contentType: ContentType = ContentType.Application.Json,