miLibris / flask-rest-jsonapi

Flask extension to build REST APIs around JSONAPI 1.0 specification.
http://flask-rest-jsonapi.readthedocs.io
MIT License
597 stars 153 forks source link

Unable to decide schema before POST #108

Closed schedutron closed 5 years ago

schedutron commented 6 years ago

We're using flask-rest-jsonapi library for our project, which involves creating a discount code for events. The problem we are facing is that we are unable to make discount code's schema dynamic - i.e., it should change based on the data we receive from clients. Here is the sample POST data:

{
  "data": {
    "attributes": {
      "code": "DC101",
      "discount-url": "https://my-discount-url.com",
      "value": "100",
      "type": "amount",
      "is-active": "false",
      "tickets-number": "404",
      "min-quantity": "0",
      "max-quantity": "100",
      "valid-from": "2017-06-18T18:30:00+00:00",
      "valid-till": "2017-06-24T18:30:00+00:00",
      "used-for": "ticket"
    },
    "type": "discount-code",
    "relationships": {
      "event": {
        "data": {
            "id": "1",
            "type": "event"
          }
      },
      "tickets": {
          "data": [{
              "id": "31",
              "type": "ticket"
          }]
        }
    }
  }
}

Based on the used-for attribute value, we want the schema to change - if the value is ticket, schema should be DiscountCodeSchemaTicket and if the value is event, it should be DiscountCodeSchemaEvent. We added this functionality in the before_post method:

def before_post(self, args, kwargs, data):
        if data['used_for'] == 'ticket':
            self.schema = DiscountCodeSchemaTicket
            ...

But the problem is that this method isn't really called "before" the post method, but actually in between, after the schema has already been computed: https://github.com/miLibris/flask-rest-jsonapi/blob/a5ec222e5a55fcdc583a88cb9248977f9200c4d1/flask_rest_jsonapi/resource.py#L160

Thus, the code in before_post doesn't make any difference to the schema, and the default schema is chosen everytime.

Now, this can be fixed by introducing a method, say decide_schema() that does the dynamic schema change before it is computed, but that requires change in this library's code. Since we want our project's code to be self-sufficient, can you suggest a way to accomplish this without making changes to the library code?

dr0pdb commented 6 years ago

@akira-dev Could you please help here ?

kumy commented 6 years ago

@schedutron We got the same issue. Our solution was to add a new hook, see https://github.com/geokrety/flask-rest-jsonapi/commit/681c3fc198362ed5609d065aeb417664da0ee291

kumy commented 6 years ago

Please find PR #123

schedutron commented 6 years ago

Thanks a lot, @kumy!