使用具有余烬数据的分形变换器

时间:2014-08-04 21:37:59

标签: json ember.js laravel

我使用PHP联盟的Fractal作为我的API的变换器。但是,我认为我必须做错事,因为项目变换器将所有内容包装在一个数组中,就像我认为的那个符合JSON API标准的集合一样。

因此对于ID为1的用户,我得到这样的内容:

{  
"users":[  
   {  
      "id":1,
      "firstName":"Jacob",
      "surname":"Windsor",
   }
  ]
}

肯定应该是这个?

{  
"users":
   {  
      "id":1,
      "firstName":"Jacob",
      "surname":"Windsor",
   }
}

我正在使用ember.js,这导致了命名约定的问题。

我正在使用Laravel,在我的userController我有类似的东西:

public function show($id)
{
    $user = User::find($id);
    return $this->respondItem($user);
}

然后在apiController中,所有内容都来自:

public function respond($response, $status = 200){
    return Response::make($response, $status);
}


public function respondTransform($resource){
    $fractal = new Fractal\Manager();
    $fractal->setSerializer(new JsonApiSerializer());
    return $this->respond($fractal->createData($resource)->toJson());
}

public function respondItem($data, $transformer = null, $namespace = null){
    ! isset($transformer) ? $transformer = $this->transformer : $transformer = $transformer;
    ! isset($namespace) ? $namespace = $this->namespace : $namespace = $namespace;
    $resource = new Item($data, $transformer, $namespace);
    return $this->respondTransform($resource);
}

我一定是做错了。分形文档没有专门针对项目集合的示例,所以我不确定我做了什么。

3 个答案:

答案 0 :(得分:3)

所以看起来Fractal并不完全服从ember-data的约定,这是一个烦人的问题,但很容易使用custom serialziers来克服。

我有一个名为CustomJsonSerializer的psr-4自动加载文件,我已将其包含在ApiController类中。如果你按照PHP联盟网站上的文章(上面发布),它很容易做到。我有这两种方法。

public function collection($resourceKey, array $data)
{
    return array($resourceKey ?: 'data' => $data);
}

/**
 * Serialize an item resource
 *
 * @param string $resourceKey
 * @param array $data
 *
 * @return array
 */
public function item($resourceKey, array $data)
{
    return [$resourceKey => $data];
}

您可以看到该集合正常响应,即我没有更改它。但是item方法只响应没有额外的数组。简单!你必须包括所有其他方法,我还没有完成分页,但它应该相当简单。

我希望这有助于任何想要在Fractal中使用ember-data的人。我强烈推荐它,分形让我的生活变得如此简单。您可以自己构建变换器,但它可以使它变得更容易,并且将来更容易修改。

编辑:

请确保在这两种方法中保留$resourceKey。您需要在调用变压器时使用它并进行设置。 | Ember-data需要资源键。

答案 1 :(得分:1)

假设您的userController延长ApiController,您可以执行以下操作:

public function show($id)
{
    $user = User::findOrFail($id);

    return $this->setStatusCode(200)->withItem($user, new UserTransformer);
}

您需要实现UserTransformer类。如果您需要帮助,请在评论中告诉我。

答案 2 :(得分:0)

我实际上发现JsonApiSerializer的一个更简单的调整做了我对Ember所需要的:

(我刚拿出count($data)支票)

<?php
namespace Acme\Serializer;

use RuntimeException;

use League\Fractal\Serializer\JsonApiSerializer;

class EmberSerializer extends JsonApiSerializer
{


    /**
     * Serialize the top level data.
     *
     * @param string $resourceKey
     * @param array $data
     *
     * @return array
     */
    public function serializeData($resourceKey, array $data)
    {
        if (! $resourceKey) {
            throw new RuntimeException('The $resourceKey parameter must be provided when using '.__CLASS__);
        }

        return array($resourceKey => $data);
    }

}