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

Related relationships links returned incorrectly in example app #49

Closed jcampbell closed 7 years ago

jcampbell commented 7 years ago

I can provide the following steps to reproduce, but I have not been able to understand yet what's causing the issue, so I wanted to open this ticket to flag it.

  1. Run the example api.py.
  2. Post a new object to /persons:
    {
    "data": {
    "type": "person",
    "attributes": {
      "name": "Person1"
    }
    }
    }
  3. Get the person's (empty) relationships object at /persons/1/relationships/computers
    {
    "links": {
    "self": "/persons/1/relationships/computers",
    "related": "/persons/1/computers"
    },
    "data": [],
    "jsonapi": {
    "version": "1.0"
    }
    }
  4. Post a new object to /persons
    {
    "data": {
    "type": "person",
    "attributes": {
      "name": "Person2"
    }
    }
    }
  5. Observe that the "relationships" -> "computers" -> "links" -> "related" url is incorrect (refers to person 1). That appears to stick through other permutations (subsequent gets), but depends on having queried previously for another person's relationships.
    {
    "data": {
    "type": "person",
    "id": "2",
    "attributes": {
      "display_name": "PERSON2 <None>",
      "birth_date": null
    },
    "relationships": {
      "computers": {
        "links": {
          "self": "/persons/2/relationships/computers",
          "related": "/persons/1/computers"
        }
      }
    },
    "links": {
      "self": "/persons/2"
    }
    },
    "links": {
    "self": "/persons/2"
    },
    "jsonapi": {
    "version": "1.0"
    }
    }

I have not investigated deeply enough to understand why this is happening (or tested outside of the example sqlite), but wanted to open the issue in hopes the author can identify the problem since it definitely doesn't seem to match the JSONAPI spec or desired behavior.

sodre commented 7 years ago

I can confirm @jcampbell issue as well. I wrote a small script for testing it using curl and jq.

The main difference is that the script adds an extra person before accessing the empty relationship in step 3. The script does that to ensure everything was working as expected before performing that step.

#!/usr/bin/env bash
set -ef -o pipefail
shopt -s expand_aliases

alias jsonapi='curl -sS -H "Accept: application/vnd.api+json" -H "Content-Type: application/vnd.api+json"'

# Assumes you have run python api.py
URL=http://localhost:5000

echo -n 'Database is clean: '
jsonapi $URL/persons | jq -e '.meta.count == 0'

echo -n 'Add Person 1 and links.related is as expected: '
jsonapi $URL/persons -X POST -d '{
    "data": {
        "type": "person",
        "attributes": {
            "name": "Person1"
        }
    }
}' | jq -e '.data.relationships.computers.links.related == "/persons/1/computers"'

echo -n 'Add Person 2 and links.related is as expected: '
jsonapi $URL/persons -X POST -d '{
    "data": {
        "type": "person",
        "attributes": {
            "name": "Person2"
        }
    }
}' | jq -e '.data.relationships.computers.links.related == "/persons/2/computers"'

# Access Person's 1 (empty) relationship with computers
echo -n 'Access Person 1 (empty) relationship with computers: '
jsonapi $URL/persons/1/relationships/computers | jq -e '.links.self == "/persons/1/relationships/computers"'

echo -n 'Add Person 3 and links.related is as expected: '
jsonapi $URL/persons -X POST -d '{
    "data": {
        "type": "person",
        "attributes": {
            "name": "Person3"
        }
    }
}' | jq -e '.data.relationships.computers.links.related == "/persons/3/computers"'

echo 'All tests passed.'
jcampbell commented 7 years ago

@sodre: thanks for confirming the issue and building a great patch set. Can get this merged in?