summaryrefslogtreecommitdiff
path: root/src/channel
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-10-19 00:57:20 -0400
committerOwen Jacobson <owen@grimoire.ca>2024-10-19 00:57:20 -0400
commitad00b553d845dba8af7b0e9fa2930209aee1dd62 (patch)
tree0a91c3c0113b2618730d3160f311c083e95b0581 /src/channel
parent635d92eb4ffc5a1c94cba784a2a4f18e1cb5effc (diff)
Make the responses for various data creation requests more consistent.
In general: * If the client can only assume the response is immediately valid (mostly, login creation, where the client cannot monitor the event stream), then 200 Okay, with data describing the server's view of the request. * If the client can monitor for completion by watching the event stream, then 202 Accepted, with data describing the server's view of the request. This comes on the heels of a comment I made on Discord: > hrm > > creating a login: 204 No Content, no body > sending a message: 202 Accepted, no body > creating a channel: 200 Okay, has a body > > past me, what were you on There wasn't any principled reason for this inconsistency; it happened as the endpoints were written at different times and with different states of mind.
Diffstat (limited to 'src/channel')
-rw-r--r--src/channel/routes/channel/post.rs23
-rw-r--r--src/channel/routes/channel/test.rs2
-rw-r--r--src/channel/routes/post.rs14
-rw-r--r--src/channel/routes/test.rs16
4 files changed, 39 insertions, 16 deletions
diff --git a/src/channel/routes/channel/post.rs b/src/channel/routes/channel/post.rs
index a71a3a0..b489a77 100644
--- a/src/channel/routes/channel/post.rs
+++ b/src/channel/routes/channel/post.rs
@@ -1,7 +1,7 @@
use axum::{
extract::{Json, Path, State},
http::StatusCode,
- response::{IntoResponse, Response},
+ response::{self, IntoResponse},
};
use crate::{
@@ -9,7 +9,7 @@ use crate::{
clock::RequestedAt,
error::{Internal, NotFound},
login::Login,
- message::app::SendError,
+ message::{app::SendError, Message},
};
pub async fn handler(
@@ -18,12 +18,13 @@ pub async fn handler(
RequestedAt(sent_at): RequestedAt,
login: Login,
Json(request): Json<Request>,
-) -> Result<StatusCode, Error> {
- app.messages()
+) -> Result<Response, Error> {
+ let message = app
+ .messages()
.send(&channel, &login, &sent_at, &request.body)
.await?;
- Ok(StatusCode::ACCEPTED)
+ Ok(Response(message))
}
#[derive(serde::Deserialize)]
@@ -31,12 +32,22 @@ pub struct Request {
pub body: String,
}
+#[derive(Debug)]
+pub struct Response(pub Message);
+
+impl IntoResponse for Response {
+ fn into_response(self) -> response::Response {
+ let Self(message) = self;
+ (StatusCode::ACCEPTED, Json(message)).into_response()
+ }
+}
+
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct Error(#[from] pub SendError);
impl IntoResponse for Error {
- fn into_response(self) -> Response {
+ fn into_response(self) -> response::Response {
let Self(error) = self;
#[allow(clippy::match_wildcard_for_single_variants)]
match error {
diff --git a/src/channel/routes/channel/test.rs b/src/channel/routes/channel/test.rs
index c6541cd..b895b69 100644
--- a/src/channel/routes/channel/test.rs
+++ b/src/channel/routes/channel/test.rs
@@ -27,7 +27,7 @@ async fn messages_in_order() {
for (sent_at, body) in &requests {
let request = post::Request { body: body.clone() };
- post::handler(
+ let _ = post::handler(
State(app.clone()),
Path(channel.id.clone()),
sent_at.clone(),
diff --git a/src/channel/routes/post.rs b/src/channel/routes/post.rs
index d694f8b..a05c312 100644
--- a/src/channel/routes/post.rs
+++ b/src/channel/routes/post.rs
@@ -17,14 +17,14 @@ pub async fn handler(
_: Login, // requires auth, but doesn't actually care who you are
RequestedAt(created_at): RequestedAt,
Json(request): Json<Request>,
-) -> Result<Json<Channel>, Error> {
+) -> Result<Response, Error> {
let channel = app
.channels()
.create(&request.name, &created_at)
.await
.map_err(Error)?;
- Ok(Json(channel))
+ Ok(Response(channel))
}
#[derive(serde::Deserialize)]
@@ -33,6 +33,16 @@ pub struct Request {
}
#[derive(Debug)]
+pub struct Response(pub Channel);
+
+impl IntoResponse for Response {
+ fn into_response(self) -> response::Response {
+ let Self(channel) = self;
+ (StatusCode::ACCEPTED, Json(channel)).into_response()
+ }
+}
+
+#[derive(Debug)]
pub struct Error(pub app::CreateError);
impl IntoResponse for Error {
diff --git a/src/channel/routes/test.rs b/src/channel/routes/test.rs
index ffd8484..7879ba0 100644
--- a/src/channel/routes/test.rs
+++ b/src/channel/routes/test.rs
@@ -20,9 +20,10 @@ async fn new_channel() {
let name = fixtures::channel::propose();
let request = post::Request { name: name.clone() };
- let Json(response) = post::handler(State(app.clone()), creator, fixtures::now(), Json(request))
- .await
- .expect("creating a channel in an empty app succeeds");
+ let post::Response(response) =
+ post::handler(State(app.clone()), creator, fixtures::now(), Json(request))
+ .await
+ .expect("creating a channel in an empty app succeeds");
// Verify the structure of the response
@@ -96,7 +97,7 @@ async fn name_reusable_after_delete() {
// Call the endpoint (first time)
let request = post::Request { name: name.clone() };
- let Json(response) = post::handler(
+ let post::Response(response) = post::handler(
State(app.clone()),
creator.clone(),
fixtures::now(),
@@ -115,9 +116,10 @@ async fn name_reusable_after_delete() {
// Call the endpoint (second time)
let request = post::Request { name: name.clone() };
- let Json(response) = post::handler(State(app.clone()), creator, fixtures::now(), Json(request))
- .await
- .expect("new channel in an empty app");
+ let post::Response(response) =
+ post::handler(State(app.clone()), creator, fixtures::now(), Json(request))
+ .await
+ .expect("new channel in an empty app");
// Verify the structure of the response