Code Monkey home page Code Monkey logo

Comments (9)

Allin2000 avatar Allin2000 commented on May 24, 2024

root@T14P:~/fastapi-project/fastapi-learn/loco-learn/myapp# cargo loco doctor
Compiling myapp v0.1.0 (/root/fastapi-project/fastapi-learn/loco-learn/myapp)
error[E0277]: the trait bound fn(axum::Json<RecipeCreate>, loco_rs::prelude::State<loco_rs::prelude::AppContext>) -> impl std::future::Future<Output = std::result::Result<axum::http::Response<Body>, loco_rs::Error>> {create_recipe}: Handler<_, _> is not satisfied
--> src/controllers/recipes.rs:82:37
|
82 | .add("/create_recipe", post(create_recipe))
| ---- ^^^^^^^^^^^^^ the trait Handler<_, _> is not implemented for fn item fn(Json<RecipeCreate>, State<AppContext>) -> impl Future<Output = Result<Response<Body>, Error>> {create_recipe}
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait Handler<T, S>:
<axum_extra::handler::or::Or<L, R, Lt, Rt, S> as Handler<(M, Lt, Rt), S>>
<axum_extra::handler::IntoHandler<H, T, S> as Handler<T, S>>
<Layered<L, H, T, S> as Handler<T, S>>
<MethodRouter as Handler<(), S>>
note: required by a bound in loco_rs::prelude::post
--> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/axum-0.7.5/src/routing/method_routing.rs:389:1
|
389 | top_level_handler_fn!(post, POST);
| ^^^^^^^^^^^^^^^^^^^^^^----^^^^^^^
| | |
| | required by a bound in this function
| required by this bound in post
= note: this error originates in the macro top_level_handler_fn (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try rustc --explain E0277.
error: could not compile myapp (lib) due to 1 previous error
root@T14P:~/fastapi-project/fastapi-learn/loco-learn/myapp#

from loco.

Allin2000 avatar Allin2000 commented on May 24, 2024

correct pub async fn create_recipe(State(ctx): State,Json(params): Json) ->Result
error pub async fn create_recipe(Json(params): Json,State(ctx): State) ->Result
This error is unbelievable!!!!!!!!

from loco.

Muxoid avatar Muxoid commented on May 24, 2024

I had the same error and it caused me a lot of confusion I made this pull request to solve it and make the errors more readable.

import this: use axum::debug_handler;

and add this macro to your handler that is causing the issue like so.

#[debug_handler]
pub async fn echo(req_body: String) -> String {
req_body
}

from loco.

Allin2000 avatar Allin2000 commented on May 24, 2024

documents : Building a CRUD API

pub async fn update( Path(id): Path,State(ctx): State,Json(params): Json) -> Result {
let item = load_item(&ctx, id).await?;
let mut item = item.into_active_model();
params.update(&mut item);
let item = item.update(&ctx.db).await?;
format::json(item)
}

An error is reported when changing the order of function parameters.

pub async fn update( Path(id): Path,Json(params): Json,State(ctx): State) -> Result {
let item = load_item(&ctx, id).await?;
let mut item = item.into_active_model();
params.update(&mut item);
let item = item.update(&ctx.db).await?;
format::json(item)
}

error[E0277]: the trait bound is not satisfied
--> src/controllers/recipes.rs:82:37
|
82 | .add("/create_recipe", post(create_recipe))
| ---- ^^^^^^^^^^^^^ the trait is not implemented for fn item
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait :
<axum_extra::handler::or::Or<L, R, Lt, Rt, S> as Handler<(M, Lt, Rt), S>>
<axum_extra::handler::IntoHandler<H, T, S> as Handler<T, S>>
<Layered<L, H, T, S> as Handler<T, S>>
<MethodRouter as Handler<(), S>>
note: required by a bound in loco_rs::prelude::post
--> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/axum-0.7.5/src/routing/method_routing.rs:389:1

from loco.

Muxoid avatar Muxoid commented on May 24, 2024

Yes, the order matters for the parameters. If you add this macro #[debug_handler] to your function you will get better error messages.

#[debug_handler]
pub async fn update( Path(id): Path,Json(params): Json,State(ctx): State) -> Result {
let item = load_item(&ctx, id).await?;
let mut item = item.into_active_model();
params.update(&mut item);
let item = item.update(&ctx.db).await?;
format::json(item)
}

Like this but do not forget to import the following.

use axum::debug_handler;

from loco.

Allin2000 avatar Allin2000 commented on May 24, 2024

This design is very unreasonable.Is it possible to make the order of function parameters not affected?
1.documents : Building a CRUD API . function (list ,add,update,remove,get_one) .The order of arguments for these functions in the official documentation is confused.
2.The second is that the misinformation is outrageous.
3. #[debug_handler] I only found out about this plan after talking to you.

from loco.

isaacdonaldson avatar isaacdonaldson commented on May 24, 2024

For what's worth, I don't think the design is "very unreasonable" - like everything, it has tradeoffs. The loco server handlers are actually from a library called axum, and it makes heavy use of macros to make some things easier for developers (some runtime errors become compile time errors). One of the side effects is that the error messages are very unhelpful, which is why they created another macro to give better error reporting. I'll grant you it's not the easiest to discover, but you asked a question and got an answer from the community - seems like an okay exchange to me.

I'm not sure what you mean by "the misinformation is outrageous".

Back to talking about tradeoffs, the axum crate provides "extractors" (I might be misremembering the terminology) that allow developers to pattern match on params passed to the handler. Being able to pattern match on these params is a powerful tool to allows developers to be declarative, instead of having to imperatively do the same thing. But like all HTTP route handlers, they are bound by the same rules; namely, you can't read the body of an HTTP request/response stream more than once (as found in other languages like JavaScript). The order of the params being passed to the handler matters because the order of operations matter (axum order of extractors documentation). If you hate the extractors you can always read the body from the request itself as well, dealers choice (although not as simple).

I don't speak for loco, but it would be quite the undertaking to document all the libraries it uses on top of the loco specific behaviours. I WOULD agree that having a blurb in the documentation about order of extractors mattering, and a link to the respective documentation would be a net benefit.

from loco.

Allin2000 avatar Allin2000 commented on May 24, 2024

pub async fn fetch_receipe(Path(id): Path, State(ctx): State) correct
pub async fn fetch_receipe(State(ctx): State,Path(id): Path) correct

but

async fn create_recipe(State(ctx): State,Json(params): Json) correct
async fn create_recipe(Json(params): Json,State(ctx): State) error

That's why it's puzzling.

from loco.

isaacdonaldson avatar isaacdonaldson commented on May 24, 2024

Something subtle that is mentioned in the docs I linked above is the disclaimer that extractors who implement the FromRequest trait HAVE to be last in order, and ones that implement the FromRequestParts trait can be anywhere but last. Another thing mentioned is that no type can implement both FromRequest and FromRequestParts. Since the Json extractor needs to read the body of the request, it can't have any extractor go after it (can only read the body stream once). This means it must implement FromRequest, requiring it to be put last in the order. The State and Path extractors do not read from the body stream and therefore implement the FromRequestParts trait, meaning the order can be switched around as long as none are put after an extractor that implements FromRequest.

In your first example, both State and Path implement FromRequestParts and have no extractors that implement FromRequest, so the order of them can be changed around. But in the second example, Json implements FromRequest (meaning it reads the http request body stream) so it HAS to go last, that's why there is an error when it is not put last.

from loco.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.