laravel-json-api / laravel

JSON:API for Laravel applications
MIT License
541 stars 41 forks source link

Exception when encoding binary data #219

Closed ben221199 closed 1 year ago

ben221199 commented 1 year ago

Hello @lindyhopchris,

At the moment I'm implementing DNSSEC in my DNS system using an API. Logically, there will be binary data and this data isn't neccesary UTF-8. However, when encoding, it only works when I use utf8_encode() on my binary data, else it will give me the following error:

Meta for resource type `dns_record` cannot be converted into JSON. Please check its Schema returns valid data. at /srv/www/site.com/vendor/laravel-json-api/neomerx-json-api/src/Representation/DocumentWriter.php:304)
[stacktrace]
#0 /srv/www/site.com/vendor/laravel-json-api/neomerx-json-api/src/Representation/DocumentWriter.php(304): assert(false, 'Meta for resour...')
#1 /srv/www/site.com/vendor/laravel-json-api/neomerx-json-api/src/Representation/DocumentWriter.php(89): Neomerx\\JsonApi\\Representation\\DocumentWriter->getResourceRepresentation(Object(LaravelJsonApi\\Encoder\\Neomerx\\Parser\\IdentifierAndResource), Object(Neomerx\\JsonApi\\Representation\\FieldSetFilter))
#2 /srv/www/site.com/vendor/laravel-json-api/neomerx-json-api/src/Encoder/Encoder.php(195): Neomerx\\JsonApi\\Representation\\DocumentWriter->addResourceToIncluded(Object(LaravelJsonApi\\Encoder\\Neomerx\\Parser\\IdentifierAndResource), Object(Neomerx\\JsonApi\\Representation\\FieldSetFilter))
#3 /srv/www/site.com/vendor/laravel-json-api/neomerx-json-api/src/Encoder/Encoder.php(106): Neomerx\\JsonApi\\Encoder\\Encoder->encodeDataToArray(Object(Generator))
#4 /srv/www/site.com/vendor/laravel-json-api/encoder-neomerx/src/CompoundDocument.php(61): Neomerx\\JsonApi\\Encoder\\Encoder->encodeData(Object(Generator))
#5 /srv/www/site.com/vendor/laravel-json-api/encoder-neomerx/src/Document.php(191): LaravelJsonApi\\Encoder\\Neomerx\\CompoundDocument->encode()
#6 /srv/www/site.com/vendor/laravel-json-api/core/src/Core/Responses/Internal/ResourceCollectionResponse.php(88): LaravelJsonApi\\Encoder\\Neomerx\\Document->toJson(0)

Is there any fix for this? I don't need my data UTF-8 encoded. JSON is capable to encode byte sequences too.

lindyhopchris commented 1 year ago

So that's an error originating from the encoder package. All it's doing is calling json_encode($value) and that is returning false i.e. PHP is failing to JSON encode the value you're providing, rather than this package failing to encode it.

My question for you is - can you get PHP's json_encode() to work with the value you're trying to put into the JSON? If so, can you share the flags that you're using to get it to work. If you can't get it to work, then there's not really much I can do as it's a PHP thing!

FYI utf8_encode is deprecated. My guess (though haven't tried anything) is you'd need to base64 encode the value.

ben221199 commented 1 year ago

I removed my utf8_encode calls from my model function getDNSDataAttribute, so that my model and other inside code work with GOOD values instead of UTF-8 encoded malformed data. However, in order to get the API working and have \uXXXX in my JSON output, I had to add utf8_encode to my resource object RecordResource and my schema RecordSchema. I also wrote some custom code with json_encode (when I substituted DataResponse temporary) and also had to add utf8_encode on an array item.

nastoychev commented 1 year ago

Whenever I transport binary data I convert it to base64 format.

lindyhopchris commented 1 year ago

Yeah base64 would seem like the sensible approach.

@ben221199 I'm going to close this issue. That exception is caused by json_encode() failing, which I can't do anything about.