Code Monkey home page Code Monkey logo

poem's People

Contributors

attila-lin avatar banool avatar bestgopher avatar brunobell avatar dbanty avatar ddtkey avatar dependabot[bot] avatar eugeny avatar getong avatar gleb-chipiga avatar glebpom avatar itsbalamurali avatar jackymao avatar kolloch avatar lazywalker avatar liangyongrui avatar liberwang1013 avatar marvinguo avatar miikka avatar mzachar avatar nahuel-m avatar phungleson avatar saculrennorb avatar schitcrafter avatar simoneromano96 avatar stepantubanov avatar sunli829 avatar umaynit avatar versbinarii avatar zuiyu1998 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

poem's Issues

Bug

When I first to use poem, I copied the examples, and cargo run. It looks like this.
How to solve it? v0.4.5
截屏2021-08-31 下午7 58 45

[poem-openapi] How about put some common attributes on the impl scope?

Description of the feature

How about put some common attributes on the impl scope?
such as prefix_path and openapi tag.

Code example (if possible)

#[OpenApi]
#[oai(prefix_path = "/pet", tag = ApiTags::Pet)]
impl Api {
    #[oai(path = "/", method = "post")]
    async fn add_pet(&self, pet: Json<Pet>) -> Result<()> {
        todo!()
    }
// ...
}

PgSessionStore to be used with nested routing

Hi @sunli829

Again, this is probably due to my limited knowledge of poem.

Basically, I want to use PgSessionStore.

Route::new().at(
    "query",
    post(GraphQL::new(schema))
    .get(graphql_playground)
    .with(server_session),
)

It throws error the trait bound `impl std::future::Future: SessionStorage` is not satisfied

If I try something like the example

Route::new().at(
    "query",
    post(GraphQL::new(schema))
    .get(graphql_playground),
).with(server_session)

Then I don't know how to turn in back as a Route (am setting up nested routing).

Couple of observation regarding dbsession

Good day @sunli829

I am still testing with poem, I want to share small observation with dbsession for consideration or further checking.

  1. For postgres, not sure if it is correct or not but it looks like it will fail if session column is not JSONB. If it is then maybe there should be a note.

  2. Cleanup task should probably be configurable. When we have multiple poem servers running, we probably don't want every server to ping database to do clean up. I am not sure what the best way to approach this as some pros and cons of each setup or we just need to accept the duplicate jobs?

  3. Not very high priority, the value of in session in db looks like this {"id": "\"xxx\""}, it looks like the library does serialising twice at some points. It doesn't seem to affect how it works, nevertheless it is kind of nice to have correct json presentation.

PgSessionStore

Hi @sunli829, awesome work as always! this library looks as clean as async-graphql and +1 for the name 😄

Description of the feature

Currently it does not support PgSessionStore, so you have any thought about it?

Like should it be here or which library to use with Pg?

Suggestion

The example looks like this.
`use poem::{handler, route, web::Path, RouteMethod, Server};

#[handler]
fn hello(Path(name): Path) -> String {
format!("hello: {}", name)
}

#[tokio::main]
async fn main() {
let app = route().at("/hello/:name", RouteMethod::new().get(hello));
let server = Server::bind("127.0.0.1:3000").await.unwrap();
server.run(app).await.unwrap();
}but i think like this below is nice.use poem::{handler, route, web::Path, RouteMethod, Server};

#[handler]
fn hello(Path(name): Path) -> String {
format!("hello: {}", name)
}

#[tokio::main]
async fn main() {
let app = route().get("/hello/:name", hello);
let server = Server::bind("127.0.0.1:3000").await.unwrap();
server.run(app).await.unwrap();
}`

this is easy to understand and write and more friendly to users. I think.

Poem_Openapi: Parse Parameter Description per ///

Hey there :)

Would it be possible to parse Parameter Descriptions via ///-comments, like with struct fields etc, instead of the 'desc=' notation?

I struggled to find descriptions in the first place...

async fn test(&self, #[oai(desc = "ABC")] v: Query<i32>) {

So maybe in this case:

async fn test(&self, 
    /// desc
    v: Query<i32>
) { 

or comparable? Or would that be to inconsistent with linebreaks?

ServerSide Cache feature

Description of the feature

ServerSide Cache is a common scenario in web application especially with heavy loaded, it will be good to have a Cache extractor which can use DiskCache or RedisCache as CacheStore. it's quite similar to ServerSession.

Thanks :)

[poem-openapi] Define Custom Response with generic will compile error

Steps to Reproduce the Problem

use poem_openapi::{ApiResponse, Object, payload::Json};

#[derive(Object)]
pub struct SuccessResponses<T> {
    status: i32,
    data: T,
}

#[derive(Object)]
pub struct ErrorMessage {
    code: i32,
    reason: String,
}


#[derive(ApiResponse)]
pub enum CustomApiResponse<T> {
    #[oai(status = 200)]
    Ok(Json<SuccessResponses<T>>),
    /// Returns when the BadRequest.
    #[oai(status = 400)]
    BadRequest,
}

this is error message:

error[E0412]: cannot find type `T` in this scope
 --> src\main.rs:6:11
  |
6 |     data: T,
  |           ^ not found in this scope

error[E0412]: cannot find type `T` in this scope
  --> src\main.rs:19:30
   |
19 |     Ok(Json<SuccessResponses<T>>),
   |                              ^ not found in this scope

error[E0107]: missing generics for struct `SuccessResponses`
 --> src\main.rs:4:12
  |
4 | pub struct SuccessResponses<T> {
  |            ^^^^^^^^^^^^^^^^ expected 1 generic argument
  |
note: struct defined here, with 1 generic parameter: `T`
 --> src\main.rs:4:12
  |
4 | pub struct SuccessResponses<T> {
  |            ^^^^^^^^^^^^^^^^ -
help: add missing generic argument
  |
4 | pub struct SuccessResponses<T><T> {
  |            ~~~~~~~~~~~~~~~~~~~

error[E0107]: missing generics for enum `CustomApiResponse`
  --> src\main.rs:17:10
   |
17 | pub enum CustomApiResponse<T> {
   |          ^^^^^^^^^^^^^^^^^ expected 1 generic argument
   |
note: enum defined here, with 1 generic parameter: `T`
  --> src\main.rs:17:10
   |
17 | pub enum CustomApiResponse<T> {
   |          ^^^^^^^^^^^^^^^^^ -
help: add missing generic argument
   |
17 | pub enum CustomApiResponse<T><T> {
   |          ~~~~~~~~~~~~~~~~~~~~

Specifications

  • Version: latest
  • Platform: Windows

Middleware to protect authenticated routes from unauthenticated access.

If a session is authenticated, then the request should be dispatched to the matching handler and if unauthenticated, it should be redirected to a user specified route, ideally a sign in route.

Related project for Actix-Web: https://github.com/realaravinth/actix-auth-middleware

@sunli829 As I have started using Poem since yesterday so currently I'm in leeches mode but as I grow my understanding of poem I will start contributing to the project.

Debug for Extensions

I am developing some middleware and it seems a bit hard to know how req.extensions looks like.

It would be helpful if I can debug Extensions so that I can tell how the middleware interacts with each other.

Thanks.

Cookie middleware, can it support user-defined configuration properties?

Description of the feature

Currently with CookieJar, each new Cookie stored requires manual configuration of security-related properties, which is flexible, but there is a lot of duplication of work being done.

For a site, usually, the cookie security policy is kept consistent, and there are fewer scenarios where each key is configured individually.

And currently poem, cookie middleware is automatically registered after the feature is turned on, so that the user lacks some control over the initialization of the attributes.

I suggest: Cookie middleware, the user supports custom configuration at the start of the framework and can override the default loading of the cookie middleware.
Subsequent Cookie default to go configured security properties, the use of light and elegant.

[poem-openapi] Expose generated json

Description of the feature

Hi, first of all good work with poem and poem-openapi, I'm enjoying a lot using them and I'll probably migrate some projects to it.

Anyway, I'd like to be able to get (and maybe serve) the generated .json file that contains the open api specification; it would also be nice to be able to deactivate the ui feature entirely.

This is because I prefer redoc and I'd like to inspect/edit the final open api document.

Code example (if possible)

#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
    let api_service = OpenApiService::new(Api)
        .title("Hello World")
        .server("http://localhost:3000/api");

    // Get open api spec
    let openapi_spec = api_service.get_spec();

    let listener = TcpListener::bind("127.0.0.1:3000");

    poem::Server::new(listener)
        .await?
        .run(
            Route::new()
                .nest("/api", api_service)
                .nest("/openapi.json", serve_openapi_spec(openapi_spec))
        )
        .await
}

The server-side session crash the whole site with redis reload

Expected Behavior

When the redis server perform a clean reload, the Poem should treat all sessions as invalid and return None with Session struct.

Actual Behavior

All pages/url return 500 with a message

Response was of incompatible type: "Response type not string compatible." (response was nil)

Steps to Reproduce the Problem

  1. run the redis-session demo(with the patched version #73)
  2. reload the page several times to make sure that the session is working
  3. take down the redis server, remove the persistent files if needed to ensure that all caches clear
  4. restart the redis server
  5. reload our demo page, we should get 500 as i mentioned above

Specifications

  • Version: 1.0.8
  • Platform: macOS, debian, alpine

Reason why WebSocket connection works on Chromium but not Firefox?

I would normally submit this as a bug but I'm not sure if this is an issue with Poem or Firefox.
I have been using the WebSocket Chat example provided in this repository as a reference for a project I'm working on, however I've noticed that there is always an issue connecting to the the WebSocket with Firefox but not Chromium.

Expected Behavior

WebSocket code from the example provided in this repository should function regardless of web browser.

Actual Behavior

WebSocket fails to establish connection on Firefox but functions properly on Chromium.
Error from the Firefox console: Firefox can’t establish a connection to the server at ws://127.0.0.1:3000/ws.

Specifications

  • Poem Version: 1.0.26
  • Firefox Version: 94.0
  • Chromium Version: 95.0.4638.69 snap
  • Platform: Ubuntu 21.04

async-graphql-poem: expected struct `async_graphql::schem a::Schema`, found struct `async_graphql::Schema`

Expected Behavior

A schema built with a schema builder can be passed on to use async_graphql_poem::{GraphQL, GraphQLSubscription};

Actual Behavior

The following code

    let schema = Schema::build(Query, Mutation, SubscriptionRoot)
        .data(pool)
        .finish();
    let cors = Cors::new().allow_methods([Method::POST, Method::GET, Method::OPTIONS]);

    let app = Route::new()
        .at(
            "/graphql",
            get(graphql_playground)
                .options(GraphQL::new(schema.clone()))
                .post(GraphQL::new(schema.clone())),
        )
        .at("/ws", get(GraphQLSubscription::new(schema.clone())))
        .with(cors);

will trigger the following error


error[E0308]: mismatched types
   --> src/main.rs:173:39
    |
173 |                 .options(GraphQL::new(schema.clone()))
    |                                       ^^^^^^^^^^^^^^ expected struct `async_graphql::schema::Schema`
    |
    = note: expected struct `async_graphql::schema::Schema<_, _, _>`
               found struct `async_graphql::Schema<Query, Mutation, SubscriptionRoot>`
    = note: perhaps two different versions of crate `async_graphql` are being used?

error[E0308]: mismatched types
   --> src/main.rs:174:36
    |
174 |                 .post(GraphQL::new(schema.clone())),
    |                                    ^^^^^^^^^^^^^^ expected struct `async_graphql::schema::Schema`, f
ound struct `async_graphql::Schema`
    |
    = note: expected struct `async_graphql::schema::Schema<_, _, _>`
               found struct `async_graphql::Schema<Query, Mutation, SubscriptionRoot>`
    = note: perhaps two different versions of crate `async_graphql` are being used?

error[E0308]: mismatched types
   --> src/main.rs:176:49
    |
176 |         .at("/ws", get(GraphQLSubscription::new(schema.clone())))
    |                                                 ^^^^^^^^^^^^^^ expected struct `async_graphql::schem
a::Schema`, found struct `async_graphql::Schema`
    |
    = note: expected struct `async_graphql::schema::Schema<_, _, _>`
               found struct `async_graphql::Schema<Query, Mutation, SubscriptionRoot>`
    = note: perhaps two different versions of crate `async_graphql` are being used?

Trying to use directly async_graphql::schema::Schema doesn't work since it's private.

I'm testing out adding subscriptions to a graphql app. So far appart from this minor bump everything is just amazing!

Steps to Reproduce the Problem

Specifications

  • Version:
  • Platform:
  • Subsystem:

Clone for RequestBuilder

I am not sure it is a common use case but I am making lots of requests (mainly for testing) and each of them is slightly different.

So I am thinking of using RequestBuilder so that I can share some common headers.. etc...

However whenever I consume it into Request I cannot use request_builder any more, it would be helpful if RequestBuilder is cloneable.

Thanks!

Incorrect path to handler in openapi specification

Expected Behavior

Api1 has been installed in routing under /api1.
I would expect such a specification to be generated :

{
  "openapi": "3.0.0",
  "info": {
    "title": "Oneof",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "http://localhost:3000/api1"
    }
  ],
  "tags": [],
  "paths": {
    "/api1/create-post": {
      "post": {

Actual Behavior

Extract from the current specification http://127.0.0.1:3000/spec1.json

{
  "openapi": "3.0.0",
  "info": {
    "title": "Oneof",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "http://localhost:3000/api1"
    }
  ],
  "tags": [],
  "paths": {
    "/create-post": {
      "post": {

Steps to Reproduce the Problem

I created a test repository https://github.com/szagi3891/poem-test
You have to clone and then run with cargo run
A swagger will be available at "http://127.0.0.1:3000/ui1"

Specifications

Version: poem = "1.0.34", poem-openapi = "1.0.35"
Platform: MacOs
Subsystem:

struct Api1 {}

#[OpenApi]
impl Api1 {
    pub fn new() -> Api1 {
        Api1 {}
    }

    #[oai(path = "/create-post", method = "post")]
    async fn create_post(
        &self,
        obj: Json<MyObj>,
    ) -> CreateBlogResponse {

        CreateBlogResponse::Ok(Json(444))
    }
}

    let api1 = Api1::new();

    let api_service1 = OpenApiService::new(api1, "Oneof", "1.0").server("http://localhost:3000/api1");
    let ui1 = api_service1.swagger_ui();
    let spec1 = api_service1.spec_endpoint();


    let api2 = Api2::new();

    let api_service2 = OpenApiService::new(api2, "Oneof", "1.0").server("http://localhost:3000/api2");
    let ui2 = api_service2.swagger_ui();
    let spec2 = api_service2.spec_endpoint();

    Server::new(TcpListener::bind("127.0.0.1:3000"))
        .run(Route::new()
            .nest("/spec1.json", spec1)
            .nest("/api1", api_service1)
            .nest("/ui1", ui1)
            .nest("/spec2.json", spec2)
            .nest("/api2", api_service2)
            .nest("/ui2", ui2)
        )
        .await
        

Mysql 21.0.2 incompatible with poem-openapi 1.0.31

Hey there,
I would like to use Poem with Mysql, but they seem to be using incompatible bitvec / funty versions. On build I get a error[E0034]: multiple applicable items in scope --> C:\Users\local\.cargo\registry\src\github.com-1ecc6299db9ec823\bitvec-0.19.4\src\field.rs:307:25.

This problem seems to be known in funty and can apparently be solved by updating all dependencies to funty 2.0.0 (or at least the same version.) Unfortunately it is nested quite deeply in the dependencies.

Example Toml, full build output, and cargo tree output uploaded here: https://gist.github.com/Christoph-AK/366e6c39c24976d5bf48064e658b6670

Can this be solved from this crate?

MySQL Issue: blackbeam/rust-mysql-simple#300

name for servers

Description of the feature

When I use multi poem servers, I saw multi Info logs like this, can`t tell them apart.

2021-11-22T14:04:31.803030Z  INFO poem::server: initiate graceful shutdown
2021-11-22T14:04:31.803331Z  INFO poem::server: server stopped

Implement CorsMiddleware

struct CorsMiddleware {}

impl CorsMiddleware {
    pub fn new() {
        todo!()
    }

    pub fn allow_credentials(self, allow_credentials: bool) -> Self {
        todo!()
    }

    pub fn allow_header<T>(mut self: Self, header: T) -> Self
    where
        HeaderName: TryFrom<T>,
        <HeaderName as TryFrom<K>>::Error: Into<Error>,
    {
        todo!()
    }

    pub fn allow_method(mut self: Self, method: T) -> Self
    where
        Method: TryFrom<T>,
        <Method as TryFrom<K>>::Error: Into<Error>,
    {
        todo!()
    }

    pub fn allow_origin(mut self: Self, origin: impl Into<String>) -> Self {
        todo!()
    }

    pub fn allow_all_origin(mut self: Self) -> Self {
        todo!()
    }

    pub fn expose_header<T>(mut self: Self, header: T) -> Self
    where
        HeaderName: TryFrom<T>,
        <HeaderName as TryFrom<K>>::Error: Into<Error>,
    {
        todo!()
    }

    pub fn max_age(mut self, max_age: usize) {
        todo!()
    }
}

impl Middleware<E: Endpoint> for CorsMiddleware {
    type Output = CorsMiddlewareImpl;

    fn transform(&self, ep: E) -> Self::Output {
        todo!()
    }
}

Description is a required field for responses

Expected Behavior

All responses, regardless of how they're derived, will include a description. Specifically, this bit of the spec specifies it as a required field.

Actual Behavior

No description is included by default, and there were no (obvious) examples of how to add one. I did find out from poking around that simply adding a comment above a response variant will add a description, but this should be called out in the book (or API docs somewhere, though not sure where that'd fit).

Steps to Reproduce the Problem

Use a response like this:

#[derive(Debug, ApiResponse)]
enum Response {
    #[oai(status = 200)]
    Ok(
        Json<u64>,
    ),
}

Notice that the OpenAPI document has the response documented like this:

"responses": {
  "200": {
    "content": {
      "application/json": {
        "schema": {
          "type": "integer",
          "format": "uint64"
        }
      }
    }
  }
}

Some tooling (including the generator I maintain 😬) will fail schema validation of the document when parsing this.

Specifications

poem = { version = "1.0.24", features = ["multipart", "tempfile"] }
poem-openapi = "1.0.20"
  • Subsystem: openapi

Set query params

Hi Sunli, I am using poem::RequestBuilder to build requests for testing, how do I add query params to request?

Incorrectly generated type in openapi specification for enum

Expected Behavior

There should never be a clash in the names of the generated structures

Actual Behavior

There is currently a possible collision in the generated structure names.

Steps to Reproduce the Problem

  1. I created a test repository https://github.com/szagi3891/poem-test
  2. You have to clone and then run with cargo run
  3. A swagger will be available at "http://127.0.0.1:3000/ui2"

Specifications

  • Version: poem = "1.0.34", poem-openapi = "1.0.34"
  • Platform: MacOs
  • Subsystem:

This part was incorrectly generated in the specification, source code:

#[derive(Object, Debug, PartialEq)]
pub struct B {
    v4: String,
}

...

#[derive(OneOf, Debug, PartialEq)]
#[oai(property_name = "type")]
pub enum MyObj2 {
    A(A),
    B(B),
}

...

    #[oai(path = "/put2", method = "post")]
    async fn index2(&self, obj: Json<MyObj2>) -> Json<MyObj2> {
        obj
    }

Ps.
By the way, fantastic library. My compliments on a great job :)

Problem generating specification when Arc field is in structure

Expected Behavior

Possibility to use Object macro on a structure where one of the fields is Arc

Actual Behavior

Error message appears:
no function or associated item named register found for struct Arc<std::string::String> in the current scope

Steps to Reproduce the Problem

  1. You have to clone https://github.com/szagi3891/poem-test
  2. And then run with cargo run

Specifications

  • Version: poem = "1.0.37", poem-openapi = "1.0.37"
  • Platform: MacOs
  • Subsystem:

Structure affected by the compilation error:

#[derive(Object, Debug, PartialEq)]
struct A {
    v1: i32,
    v2: Arc<String>,
}

hope to eliminate and decouple the trace log in serve_connection

Description of the feature

I hope to eliminate and decouple the trace log in it, so that users can reference it in the form of middleware, or give a default implementation

Code example (if possible)

In some cases, I want to print a customized log, or reference a minitrace with less overhead for tracking, or add a trace uniformly_ ID and other means to troubleshoot the problem

[docs] add comparison with other web frames, esp. axum

Is it possible to add a section in docs about the comparison with other web frames, esp. axum, I found they share lots of similarities in syntax, but the comparison can go more deeper and wider besides only the syntax?

Log, trace, monitor, error monitoring

Hi Sunli, poem seems pretty good so far, I wonder where should I start looking into for in terms of log, trace, monitor, error monitoring before I want to move poem into some sort of production? Thanks!

Version is a required field in `info`

Expected Behavior

"version" is required by the library or filled in automatically in order to comply with this part of the spec.

Perhaps OpenApiService::new could required this and title (also required) as parameters? Though that'd be a breaking change which you may want to avoid. You could also make the builder return a Result to check for required params at startup, but that is also a breaking change.

The examples should also probably include version, perhaps using a macro to include the Cargo.toml version (I think this is possible and is probably what I'll do eventually).

Actual Behavior

"version" can be omitted (as it is in the examples I followed) which can lead to validation errors in other tools.

Steps to Reproduce the Problem

Omit the .version() method in setting up OpenApiService and observe that the generated document does not contain a version field under info.

Specifications

[dependencies]
poem = { version = "1.0.24", features = ["multipart", "tempfile"] }
poem-openapi = "1.0.20"

Get query params from request

Hi Sunli,

I am writing an Endpoint, using impl Endpoint, I wonder how can I get query params from request?

I am thinking of using Extractor like this, FromRequest::from_request(&request, &mut body).await?; I am probably wrong?

Thanks!

CORS Example

Hello,
I'm really enjoying using Poem, but I've got to the point with my project that I need CORS and I can't figure out how it works? Is there an example somewhere for using the CORS middleware?

I'm doing it like this:

.with( Cors::new() .allow_origin("http://localhost:3000") .allow_method(Method::POST), );

But only the last call seems to take effect?

How can I respond early in the middleware to avoid executing `ep.call()`?

I recently ran into some tricky issues migrating my project from actix-web to poem.

Problem description.

In actix-web middlerware, I can split the task into two steps.

  1. status determination success -> service.call() (similar to ep.call() in poem)
  2. status determination failure, early response -> via req.error_response() (ServiceRequest::error_response)

Step 1 can be implemented in poem, but no good solution has been found for step 2.

Referring to the middleware implementation in example, can use extensions to add a statusX
handler with extractor to extract Result<Data<StateX>> to handle it by itself,

But I have 50/60 handlers and it is not convenient to add a state to each handler.
And every time I add middleware, I need to add State* to the handler, which will make the handler very long.

I would like to ask you for some advice.

Invalid param definition in poem-openapi struct expression in method args

Expected Behavior

#[oai(path = "/hello", method = "post")]
async fn index(&self, Json(Req { a,b }): Json<Req>) -> PlainText<String> {

these code compile ok in poem/poem-openapi 1.0.28

but these code compile error in 1.0.36/1.0.37

I think the #[OpenApi] macro refactor cause this compile error,

Json should not eat a param from in route path, only Query/Path would eat param

Actual Behavior

    Checking example-openapi-hello-world v0.1.0 (/home/w/repos/fork_repos/poem/examples/openapi/hello-world)
error: Invalid param definition.
 --> openapi/hello-world/src/main.rs:9:27
  |
9 |     async fn index(&self, Json(Req { a,b }): Json<Req>) -> PlainText<String> {

Steps to Reproduce the Problem

use poem::{listener::TcpListener, Route, Server};
use poem_openapi::{param::Query, payload::{PlainText, Json}, OpenApi, OpenApiService};

struct Api;

#[OpenApi]
impl Api {
    #[oai(path = "/hello", method = "post")]
    async fn index(&self, Json(Req { a,b }): Json<Req>) -> PlainText<String> {
        match b {
            Some(name) => PlainText(format!("hello, {}!", name)),
            None => PlainText("hello!".to_string()),
        }
    }
}

#[derive(poem_openapi::Object)]
struct Req {
    a: String,
    b: Option<String>,
}

#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
    if std::env::var_os("RUST_LOG").is_none() {
        std::env::set_var("RUST_LOG", "poem=debug");
    }
    tracing_subscriber::fmt::init();

    let api_service =
        OpenApiService::new(Api, "Hello World", "1.0").server("http://localhost:3000/api");
    // let ui = api_service.swagger_ui();

    Server::new(TcpListener::bind("127.0.0.1:3000"))
        .run(Route::new().nest("/api", api_service))
        .await
}

Specifications

  • Version: 1.0.36
  • Platform: Linux
  • Subsystem:

Capture all errors

Hi Sunli,

When I test dbsession, it throws some explicit errors about the database which is un-intended.

How can we capture all errors, from all endpoints and from all middleware? so that I can mask it with something more friendly to users.

Thanks!

How to combine multiple tower middleware?

Looks like this, but the compilation fails.

route()
    .at("/hello/:name", get(hello))
    .with(AddData::new(db))
    .with(RateLimitLayer::new(5, Duration::from_secs(30)).compat())
    .with(TimeoutLayer::new(Duration::from_secs(30)).compat())

Nested routing with middleware

Hi @sunli829

This is probably due to my limited knowledge of poem, but basically I would like to use async_graphql with poem with SizeLimit middleware.

GET app/query => playground
POST app/query => async_graphql with size limit

My code is something like this at the moment

fn app() -> Route {
    let schema = ...;

    Route::new().at(
        "query",
        get(graphql_playground)
        .post(GraphQL::new(schema))
         // .with(SizeLimit::new(CONTENT_LENGTH_LIMIT)),
    )
}

let app = Route::new().nest("app", app());

If I uncomment SizeLimit then I get 400 for GET app/query as the middleware blocked it.

Can you suggest a way to make this work?

`#[oai(extract)]` does not work.

Discussed in #40

Originally posted by pymongo September 30, 2021
I want to migrate my poem route handler to poem-openapi

I read the document here, but when I add #[oai(extract = true)] got error:

| extract | It means this parameter is a Poem extractor. | bool | Y |

Screenshot_20210930_211239

Here is the StateExtractor define, it works in normal poem handler function

pub struct StateExtractor {
    pub cookie_jar: CookieJar,
    pub graph_service: Arc<GraphService>,
    pub session_store: MemoryStore,
}

#[tonic::async_trait]
impl<'a> FromRequest<'a> for &'a StateExtractor {
    type Error = std::convert::Infallible;

    async fn from_request(req: &'a Request, _body: &mut RequestBody) -> Result<Self, Self::Error> {
        Ok(req.extensions().get::<StateExtractor>().unwrap())
    }
}
```</div>

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.