vertical-knowledge / ripozo

A tool for quickly creating REST/HATEOAS/Hypermedia APIs in python
http://ripozo.readthedocs.org/
GNU General Public License v2.0
201 stars 22 forks source link

Overriding GET method to search with TSVectorType #63

Open paridin opened 8 years ago

paridin commented 8 years ago

I try to create an API which inherited from ResourceBase, The problem is i can't set every record as jsonApi, I expected,

{
  "data": [
    {
      "type": "trademarks",
      "id": "1",
      "attributes": {
        "expediente": "1717801",
        "fecha_de_presentacion": "01/02/2016 12:00:00 AM",
        "figura_juridica": "REGISTRO DE MARCA",
        "logotipo": null,
        "signo": "IGUY",
        "tipo": "NOMINATIVA",
        "titular": "SAMSONITE IP HOLDINGS S.\u00c0.R.L."
      }
    },
    .
    . rest of the data
    .
    ]
}

Got

{
    "data": {
        "attributes": {
            "trademarks": [
                {
                    "fecha_de_presentacion": "01/02/2016 12:00:00 AM",
                    "figura_juridica": "REGISTRO DE MARCA",
                    "id": 1,
                    "signo": "IGUY",
                    "logotipo": null,
                    "tipo": "NOMINATIVA",
                    "titular": "SAMSONITE IP HOLDINGS S.À.R.L.",
                    "expediente": "1717801"
                },
    .
    . rest of the data
    .
    ]
}
# python implementation using ripozo
class Trademarks(restmixins.ResourceBase):
    """
    Trademarks Class provide a resource for search Using a TSVector
    to create a search box
    """
    @apimethod(methods=['GET'])
    def search_trademark(cls, request):
        print(request.query_args)
        props = {'pks': ('id',)}
        if 'search' in request.query_args:
            search = request.query_args.pop('search')[0]
            result = TrademarkMarcanet.query.search(search).all()
        else:
            result = TrademarkMarcanet.query.all()
        response = [r.serialize() for r in result]
        props.update(dict(trademarks=make_json_safe(response)))
        return cls(properties=props, status_code=200)

exists another way to do this task using ripozo api?

timmartin19 commented 8 years ago

Assuming that you also want an endpoint to get individual trademarks the following would work:

class Trademarks(restmixins.ResourceBase): """ Trademarks Class provide a resource for search Using a TSVector to create a search box """

These are tuples

pks = 'id',
_relationships = ListRelationship(cls.resource_name, relation='Trademarks', embedded=True),
@apimethod(methods=['GET'], no_pks=True)
def search_trademark(cls, request):
    ...
    return cls(properties=props, status_code=200, no_pks=True)

In ReSTful frameworks a list of resources is actually a different resource than an individual resources. You can tell this by the fact that they have different endpoints (/resource vs /resource/:id) hence why you need a relationship to tell ripozo what they are.

Just to be clear, I didn't test this. But it should work. If it doesn't let me know and we can try to work it out.

paridin commented 8 years ago

Thanks for the response, I will try to be more clear with my trouble, I want all records were matched with a search parameter, to maintain it simple.

I have the following request: /trademarks/?search=sams

so it retrieves all records similar sams like samsonite, samsung, sams club, etc..

With my implementation of Trademarks class it works (only tested with rest client), So when I connect my API with an ember app, it give me an error based on id.

After researching and doing some test I found that the problem was in the api exposed, this one was not in the correct place.

I'm currently getting all the fields into the attributes node. But I was looking into de ripozo framework, how can I move the id and node list of values(trademarks) one level up and maintain attributes with the fields (exposed in trademarks node) in my response, to look like this my api

{
  "data": [
    {
      "type": "trademarks",
      "id": "1",
      "attributes": {
        "signo": "samsonite",
         "logotipo": null,
        //... more attributes here
         }
     }, 
     {
      "type": "trademarks",
      "id": "2",
      "attributes": {
        "signo": "samsung",
         "logotipo": null,
        //... more attributes here
         }
     }, // .. more results
]
}
timmartin19 commented 8 years ago

Hm... So I looked into this more and it seems it may be a bug with the JSONApiAdapter. I will look into getting a fix out ASAP