api-platform / api-platform

🕸️ Create REST and GraphQL APIs, scaffold Jamstack webapps, stream changes in real-time.
https://api-platform.com
MIT License
8.55k stars 960 forks source link

Decimal data type is inconsistent #898

Open trsteel88 opened 5 years ago

trsteel88 commented 5 years ago

If you have a mapping to a "decimal" orm type, the value taken must be a "string". However, when the value is returned it may be a integer.

e.g. if you save a value as "90.00", the API returns it as 90 (integer). However, you can't save as 90 (integer).

Shouldn't this be consistent? If it only accepts a string it should only give a string back?

dunglas commented 5 years ago

This looks like a bug (must be investigated), but indeed, only string should be used.

aaa2000 commented 5 years ago

I don't have the bug

If you add the property price in Book entity of api platform demo with:

    /**
     * @ORM\Column(type="decimal", nullable=true, precision=5, scale=2)
     * @Groups("book:read")
     * @ApiProperty(iri="http://schema.org/price")
     */
    public $price;

and create a book, you see the price 90.00

curl -X POST "https://localhost:8443/books" -H  "accept: application/ld+json" -H  "Content-Type: application/ld+json" -d "{  \"isbn\": \"978-2-02-130452-7\",  \"title\": \"Decimal data type is inconsistent\",  \"description\": \"a description\",  \"author\": \"foobar\",  \"publicationDate\": \"2018-12-11T19:56:37.870Z\",  \"price\": \"90.00\"}"
{
  "@context": "/contexts/Book",
  "@id": "/books/5",
  "@type": "http://schema.org/Book",
  "isbn": "978-2-02-130452-7",
  "title": "Decimal data type is inconsistent",
  "description": "a description",
  "author": "foobar",
  "publicationDate": "2018-12-11T00:00:00+00:00",
  "reviews": [],
  "price": "90.00"
}

and when you retrieve the book, you see 90.00

@trsteel88 Can you show your annotation ? Did you add scale ? Without scale, it returns the string "90"

{
  "@context": "/contexts/Book",
  "@id": "/books/6",
  "@type": "http://schema.org/Book",
  "isbn": "978-2-02-130452-7",
  "title": "Decimal data type is inconsistent",
  "description": "a description",
  "author": "foobar",
  "publicationDate": "2018-12-11T00:00:00+00:00",
  "reviews": [],
  "price": "90"
}
trsteel88 commented 5 years ago

Here is my annotation.

/**
     * @var float
     *
     * @ORM\Column(type="decimal", precision=8, scale=2)
     */
    private $totalPrice = 0.00;

The getter returns a float

public function getTotalPrice(): float
    {
        return round($this->totalPrice, 2);
    }

Response is:

{
    "@context": "/contexts/Project",
    "@id": "/projects/91",
    "@type": "Project",
    "id": 91,
    "totalPrice": 100,
...
}

I am not using a schema like you have. Is that required? Do you return a float @aaa2000

aaa2000 commented 5 years ago

In my case, it is not a float. It is the defaut behaviour of json_encode.

>>> json_encode(["price" => 90.0]);
=> "{"price":90}"
>>> json_encode(["price" => 90.0], JSON_PRESERVE_ZERO_FRACTION);
=> "{"price":90.0}"