MarcinOrlowski / laravel-api-response-builder

Builds nice, normalized and easy to consume REST JSON responses for Laravel powered APIs.
MIT License
721 stars 79 forks source link

No data conversion mapping configured for custom class. #228

Closed kuldeepy27 closed 2 years ago

kuldeepy27 commented 2 years ago

I am getting No data conversion mapping configured for all of the custom classes which i have written inside custom packages of laravel 8.

These are simple class which have only properties defined inside them. Previously they were working fine with MarcinOrlowski/laravel-api-response-builder version 2.3 with laravel 5.4. Recently I have upgraded to laravel 8.83 and MarcinOrlowski/laravel-api-response-builder to version 9.3.

Since then I am getting this error for all these custom classes.

Below is the sample code of one of the custom classes for which I am getting this error.

    <?php
    namespace insight\models\entities\aggregate_model;

    class HeaderView
    {
        public $headers;
        public $report_sub_type;
        public $error;
        public $messages;
    }

I am using thia class inside other classes and below is the code

    $results = new HeaderView();
    $results->headers = $headers;
    $results->report_sub_type = $report_sub_type;
    $results->error = false;
    $results->messages = [];

    return RB::success($results);

This is where i am getting the error for all of these custom classes.

MarcinOrlowski commented 2 years ago

There were numerous changes in config file structure in past versions, so there's a huge chance your mapping should now be slightly different than it was in version 2.x. Please see Incompatibility notes as this documents all the changes that may bite you, i.e.

You can use recent config template as reference.

kuldeepy27 commented 2 years ago

I tried configuring mapping for all these classes in response_builder.php config with toArrayConverter class and other converter classes as handler file but still getting error as mentioned below for different handlers:

toArrayConverter -> Method class namespace::toArray does not exists. ArrayableConverter -> "obj" must be instance of Illuminate\Contracts\Support\Arrayable JsonSerializableConverter -> "obj" must be instance of JsonSerializable

Possible workaround to make it work is to introduct a toArray function to all these classes as mentioned below

<?php
namespace insight\models\entities\aggregate_model;

class HeaderView
{
  public $headers;
  public $report_sub_type;
  public $error;
  public $messages;

  public function toArray(){
    return json_decode(json_encode($this),1);
  }

}

After using toArray functions, all of these classes are working absolutely fine with RB::success() method.

It's a workaround, not a legitimate solution because here we are converting class object to array. Would be nice to support class objects for success method without converting them to array.

MarcinOrlowski commented 2 years ago

If you look at the sources of the converters, for example ArrayableConverter then you notice that it first checks if this is the right type of object. And the "right" means, it implements expected interface. In case of ArrayabeConverter the object must implement Illuminate\Contracts\Support\Arrayable. Your class is not doing that, and that's the reason of your problems. So in fact all you need to do is to mark your class implementing expected interface:

<?php
namespace insight\models\entities\aggregate_model;

use Illuminate\Contracts\Support\Arrayable;

class HeaderView implements Arrayable
{
    ...

and you should be good with built-in converters. In fact all the converters works more/less the same way so just ensure your class is correctly marked with implements


PS: I dare to recommend you review your namespace naming policy. The insight\models\entities\aggregate_model is not what is commonly used and recommended, so unless you absolutely need to name it the way you did, I recommend you refactor and follow PSR-4 for sake of standards and compatibility.

MarcinOrlowski commented 2 years ago

I am closing this ticket. Feel free to reopen or comment if needed.