-
I'm making a simple api backend and I would like the insert endpoint to be able to take a single object or an array objects (without having to just wrap everything in an array) I believe that I need a struct that I can implement OneOrMany on so I created a wrapper struct around my "NewDbObject" type which is a type on a trait. My models implement this trait.
This is the error I'm getting
Ideally I could just have my insert function on my trait take a
Thank you for any help |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 9 replies
-
I'm confused how your code looks like. Maybe you could provide a larger example. It would be good to see where you declare The |
Beta Was this translation helpful? Give feedback.
-
The entry point is main.rs the endpoint localhost/enclosures/id is set up to take a json payload from the caller #[actix_rt::main]
async fn main() -> Result<(), std::io::Error> {
dotenv::dotenv().ok();
let db_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let pool = MySqlPoolOptions::new()
.max_connections(10)
.connect(&db_url).await.unwrap();
HttpServer::new(move || {
App::new()
.data(pool.clone())
.service(
web::resource("/enclosures")
.route(web::get().to(utils::get::<Enclosure>))
.route(web::post().to(utils::add::<Enclosure>))
) The payload gets sent to utils::add: pub async fn add<Model: DbObject>(db: web::Data<MySqlPool>, input: web::Json<Model::NewDbObject>) -> Result<HttpResponse, Error> {
Ok(Model::insert(db, input.into_inner())
.await
.map(|db_object| HttpResponse::Created().json(db_object))
.map_err(|_| HttpResponse::InternalServerError())?)
} Here is the trait that NewDbObject is declared on and the MaybeMany struct declaration #[async_trait]
pub trait DbObject: Send + Serialize + 'static {
type NewDbObject: Send;
async fn insert(db: web::Data<MySqlPool>, input: Self::NewDbObject) -> Result<TableId, sqlx::Error> where Self: Sized;
}
#[serde_as]
#[derive(Deserialize)]
pub struct MaybeMany<'a, NewDbObject: serde::Deserialize<'a>> {
#[serde_as(deserialize_as = "OneOrMany<_, PreferMany>")]
items: Vec<NewDbObject>
}
Declaration shown above. I haven't tried using it yet. The text I'd like to deserialize is either going to be: {
"A": "b",
"C": "d"
} or [
{
"A": "b",
"C": "d"
},
{
"A": "e",
"C": "f"
}
]
This is what I would like to do once I get the declaration building. I want the endpoint caller to be able to pass an array of JSONs or just one. I want it all shoved into a vec regardless |
Beta Was this translation helpful? Give feedback.
-
That was what I needed. Thank you |
Beta Was this translation helpful? Give feedback.
-
I just finished implementing this and I still need to wrap the payload in square brackets:
I get a 400 without the square brackets. Here's the code:
|
Beta Was this translation helpful? Give feedback.
-
I believe I was answering your question. I put items on there because a vec needs a key for every item. I believe I need this wrapper vec because I believe Here's the struct in question
I would love if I could just get this out of OneOrMany
But I believe that if I put the derive-macro on NewEnclosure I would get this:
|
Beta Was this translation helpful? Give feedback.
-
I feel like we're not on the same page so let me start over. I have a trait called We're working specifically with Enclsoure and NewEnclosure here:
This works just fine when attempting to create only one NewEnclosure. Notice the lack of square brackets
I would like to have it so I could either only provide one NewEnclosure OR provide an array of NewEnclosures
Ideally I could do one or the other. If I was only to pass one NewEnclosure I would like to not have to provide the square brackets in my payload. Forgetting everything else I've said about |
Beta Was this translation helpful? Give feedback.
-
Answer: #308 (reply in thread) |
Beta Was this translation helpful? Give feedback.
Answer: #308 (reply in thread)