Comments (9)
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.
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.
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.
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.
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.
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.
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.
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.
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)
- Extensibility of AppContext HOT 3
- Cron/Scheduler support? HOT 6
- Adding `ilike` to model query dsl HOT 4
- docs: build a "rosetta stone" for frameworks vs "how its done in Loco"
- loco-cli doesn't have the subcommand "generate" HOT 2
- Plural naming system doesn't work for atypical plurals HOT 2
- Add section: "Loco in production", and include tips about Rust default allocators (malloc) and memory after heavy loading HOT 4
- "ActiveCache" subsystem for streamlined cache service in Loco
- "ActiveData" subsystem: enable seamless and strongly typed loading of static data for an app
- Add Error processing hook HOT 3
- Getting Started section of guide has commands that do not work as expected HOT 4
- ✍️ 👋 Guest blog posts HOT 4
- Add RequestContext, and support request-scoped sessions
- add `production.yml` to `.gitignore` by default
- Add information section to documentation about order of extractors mattering HOT 3
- _ping and api/_ping? HOT 2
- Configurable Auth Token Location.
- Make it easier to change JWT algorithm HOT 2
- Use git tags for released versions of loco HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from loco.