json-server icon indicating copy to clipboard operation
json-server copied to clipboard

X-to-many relationship support via _expand (fixes #366)

Open MaxArt2501 opened this issue 8 years ago • 6 comments

I think this is a rather painless change. My only doubt is whether we should overload _expand for this, or use another special parameter, but IMO the use cases should be non-overlapping so we should be fine.

I've added some hints about it in the readme, plus some examples (I think that part wasn't quite crystal-clear).

MaxArt2501 avatar Oct 06 '17 22:10 MaxArt2501

It seems Prettier got angry at parts that I didn't touch. Huh, what now?

MaxArt2501 avatar Oct 06 '17 22:10 MaxArt2501

@MaxArt2501 I tried fixing the build here #666

metapraveen avatar Oct 19 '17 06:10 metapraveen

@MaxArt2501

If you add an array check to those lines

https://github.com/MaxArt2501/json-server/blob/756b7d2bd8e3952ec947c60c30c34e719f8d33ad/src/server/router/plural.js#L137-L149

Something along the lines of :

...
else if (_.isArray(elementValue)) {
  return elementValue.some(el => el === value)
}
...

You'd make it so the list and nested requests work with foreignId when it's an array of length 2+. Without this check, if someone was to use /:resource?foreignId={id} or /:foreign/:id/:resource and the foreignId is of length 2+, it would not find them.

haleksandre avatar Jan 20 '18 01:01 haleksandre

Maybe it's an idea worth considering, but how is that related to #366, though? This PR aims to fix that and nothing else.

MaxArt2501 avatar Jan 20 '18 10:01 MaxArt2501

While you made the many to many support on _embed, if someone were to adopt the foreign key arrays, it would indirectly break the regular (with foreign key as a query) and nested requests.

Let's say you have something like this:

{
    "authors": [
        {
            "id": 1,
            "name": "Alex",
            "postId": [1,2,3]
        },
        {
            "id": 2,
            "name": "Max",
            "postId": [3]
        }
    ],
    "posts": [
        {
            "id": 1,
            "title": "Post 1",
            "content": "Content 1",
        },
        {
            "id": 2,
            "title": "Post 2",
            "content": "Content 2",
        },
        {
            "id": 3,
            "title": "Post 3",
            "content": "Content 3",
        }
    ]
}
// Request
'/authors?postId=1'
// or
'/posts/1/authors'

// Expected Reponse
[
    {
        "id": 1,
        "name": "Alex",
        "postId": [1,2,3]
    }
]

// Actual Response
[]


// Request
'/authors?postId=3'
// or
'/posts/3/authors'

// Expected Response
[
    {
        "id": 1,
        "name": "Alex",
        "postId": [1,2,3]
    },
    {
        "id": 2,
        "name": "Max",
        "postId": [3]
    }
]

// Actual Reponse
[
    {
        "id": 2,
        "name": "Max",
        "postId": [3]
    }
]

This happens because of this line where the element value gets converted to a string. https://github.com/typicode/json-server/blob/517f5a86bd1874b01d760e1d7bc523c906a8d134/src/server/router/plural.js#L146

When you only have 1 element everything is fine but once you have 2+ elements it "breaks", since toString() will convert [1,2] to "1,2". Which means any authors with multiple posts will always get filtered out of the response because its foreign key postId will never match a single posts id

haleksandre avatar Jan 21 '18 01:01 haleksandre

any change happens?

HKhademian avatar Jun 15 '18 09:06 HKhademian