json-server
json-server copied to clipboard
PUT saves the updated item with an id that has been converted to string
{
"id": 3,
"savedActivity": true,
"title": "Data is Interconnected",
"author": {
"firstName": "Victoria",
"lastName": "Matthews"}
}
becomes
{
"id": "3",
"savedActivity": true,
"title": "Data is Interconnected",
"author": {
"firstName": "Victoria",
"lastName": "Matthews"}
}
Hi @kolbeypruitt,
Thank you for the report, that's unexpected. What's the version of JSON Server you're using?
Can you try with the beta channel? Simply install json-server with @next
:
npm install -g json-server@next
I have encountered the same, with and without using a middleware.
json-server v0.9.0
node v5.10.1
npm v3.10.6
I'll try to rollback on an older version to fix this temporarily.
So v0.8.23 does not suffer these issues.
Something else I've encountered, it looks like you're saving the ID on PUT again from the URL and not from the object which is being passed as payload? I guess that's where the ID as a String comes from. Now we can argue about this in a productive REST API, but I guess it could be useful if we could change the ID via PUT for testing purposes?
This issue exists with PATCH as well:
{ "id": 1, "name": "Sally", "level": 2 }
becomes
{ "id": "1", "name": "Sally", "level": 2 }
This was using:
json-server v0.9.0
then downgraded to v0.8.23 which fixed the issue.
So there is 0.9.1 out, anyone tested this?
This issue is still present in the version 0.9.2, at least for PATCH requests.
Well, would love to update, but with this still being present, I'll have to run on v0.8.23 then. Any plan on resolving this @typicode ?
The first thing would need to have a failing test: https://github.com/typicode/json-server/blob/master/test/server/plural.js#L553
Does someone want to make a PR?
Actually, I think I understand better why we're getting this.
If the content type is Content-Type:application/x-www-form-urlencoded
and data is sent as form data, everything gets turned to strings.
$.ajax('http://localhost:3000/posts/1', {
method: 'PUT',
data: {
id: 1,
title: 'foo',
body: 'bar',
userId: 1
}
}).then(function(data) {
console.log(data);
});
// {id: "1", title: "foo", body: "bar", userId: "1"}
On the other side, if it's sent as content-type:application/json
it's better, but the id is still changed to a string:
fetch('http://localhost:3000/posts/1', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: 1,
title: 'foo',
body: 'bar',
userId: 1
})
}).then(function(response) {
return response.json()
}).then(function(obj) {
console.log(obj)
});
Fixed on master
, I'll release a patch today or tomorrow.
For the test, I found why it wasn't detecting the issue. Deep equal comparison was used instead of the strict one (i.e. { id: '1' }
was equal to { id: 1 }
) so now it's fixed too and it correctly tests this case.
I have encountered this issue too. Cannot waiting for the new release... By the way, can I specify to use string id instead? It is not mentioned in the CLI useage.
A great project, it saves a lot of time for us. Thanks very much.
It's released (v0.9.3
) and sorry for the long wait.
By the way, can I specify to use string id instead? It is not mentioned in the CLI useage.
You can't specify, but JSON Server figures out "automatically" somehow.
For example, if you have a db.json
like this:
{
"posts": []
}
or
{
"posts": [{ "id": 1 }]
}
The next post created will be { "id": 2 }
because:
- if the array is empty, integer is used by default for
id
- if the highest
id
is an integer, it's incremented
On the other side, if you create:
{
"posts": [{ "id": "1" }]
}
When you create a new post, id
will be a uuid string.
But I don't think, or at least haven't seen a case, where it affects the front-end to have 1, 2, 3
as ids instead of '1', '2', '3'
. In the end, you just pass back the id of the resource you want, be it a string or integer.
That said, if you want, you can still intercept the response and modify id
on the fly to be a string:
https://github.com/typicode/json-server#custom-output-example
router.render = function (req, res) {
var data = res.locals.data
data.id = data.id.toString()
res.jsonp(data)
}
In 0.12.1 I can still reproduce this issue but on NESTED objects. Example:
"fruits": [
{
id: 1,
name: "banana"
},
{
id: 2,
name: "apple",
}
]
"recipes": [
]
If I do a POST on /fruits/1/recipe, the recipe gets correctly an integer ID, but fruitId is a string. Is this the desired behavior ?
This is happening for me on nested objects as well..
Still a problem for me today in 0.14.0
@typicode there is ready fix for this on nested, can you merg?
So v0.8.23 does not suffer these issues.
Something else I've encountered, it looks like you're saving the ID on PUT again from the URL and not from the object which is being passed as payload? I guess that's where the ID as a String comes from. Now we can argue about this in a productive REST API, but I guess it could be useful if we could change the ID via PUT for testing purposes?
switching to v0.8.23 works for me. Thanks.