You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel+API Platform完整示例求助及响应格式疑问

Laravel + API Platform 完整使用示例(含分页、过滤器、序列化分组)

1. 配置齐全的Model示例

以下是包含分页、过滤器、序列化分组及JSON-LD支持的Model代码,直接适配Laravel环境:

<?php

namespace App\Models;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Serializer\Filter\PropertyFilter;
use Symfony\Component\Serializer\Annotation\Groups;
use Illuminate\Database\Eloquent\Model;

#[ApiResource(
    operations: [
        new Get(normalizationContext: ['groups' => ['post:read']]),
        new GetCollection(
            normalizationContext: ['groups' => ['post:collection']],
            paginationEnabled: true,
            paginationItemsPerPage: 10, // 默认每页条数
            paginationMaximumItemsPerPage: 50 // 允许的最大每页条数
        ),
        new Post(denormalizationContext: ['groups' => ['post:write']]),
        new Put(normalizationContext: ['groups' => ['post:read']], denormalizationContext: ['groups' => ['post:write']]),
        new Delete()
    ],
    // 启用JSON-LD格式,解决@context/@id/@type缺失问题
    formats: ['jsonld', 'json', 'html']
)]
// 配置过滤器:模糊搜索、排序、返回字段过滤
#[ApiFilter(SearchFilter::class, properties: ['title' => 'partial', 'author.name' => 'exact'])]
#[ApiFilter(OrderFilter::class, properties: ['id', 'created_at'], arguments: ['orderParameterName' => 'order'])]
#[ApiFilter(PropertyFilter::class)]
class Post extends Model
{
    protected $fillable = ['title', 'content', 'author_id'];

    // 序列化分组定义
    #[Groups(['post:collection', 'post:read'])]
    public $id;

    #[Groups(['post:collection', 'post:read', 'post:write'])]
    public $title;

    #[Groups(['post:read', 'post:write'])]
    public $content;

    #[Groups(['post:collection', 'post:read'])]
    public $created_at;

    // 关联关系示例
    public function author()
    {
        return $this->belongsTo(User::class);
    }
}

2. 自定义处理器示例

如果需要在CRUD流程中加入自定义业务逻辑,比如创建资源时自动关联当前用户:

<?php

namespace App\Processor;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\Models\Post;
use Symfony\Component\Serializer\SerializerInterface;

class PostCreateProcessor implements ProcessorInterface
{
    public function __construct(private readonly SerializerInterface $serializer) {}

    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = [])
    {
        // 按序列化分组反序列化数据到模型
        /** @var Post $post */
        $post = $this->serializer->deserialize(
            json_encode($data),
            Post::class,
            'json',
            ['groups' => ['post:write']]
        );

        // 自定义逻辑:绑定当前登录用户为作者
        $post->author_id = auth()->id();

        $post->save();

        return $post;
    }
}

要启用该处理器,只需在#[ApiResource]的对应操作中指定:

new Post(
    denormalizationContext: ['groups' => ['post:write']],
    processor: PostCreateProcessor::class
)

3. 解决@context/@id/@type字段缺失问题

Laravel环境下API Platform默认未启用JSON-LD格式,才会导致这些字段丢失,两种解决方式:

  1. 在Model中配置支持JSON-LD:如上面Model示例中的formats: ['jsonld', 'json', 'html'],请求时携带Accept: application/ld+json头即可返回带JSON-LD字段的响应。
  2. 全局设置默认格式为JSON-LD:修改config/api_platform.php:
return [
    // ...
    'formats' => [
        'jsonld' => ['application/ld+json'],
        'json' => ['application/json'],
    ],
    'default_format' => 'jsonld',
    // ...
];

4. 你的PushToken模型&处理器适配建议

针对你现有的PushToken代码,调整后即可满足需求:

修改后的PushToken模型

<?php

namespace App\Models;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use Symfony\Component\Serializer\Annotation\Groups;
use Illuminate\Database\Eloquent\Model;

#[ApiResource(
    operations: [
        new Get(normalizationContext: ['groups' => ['push_token:read']]),
        new GetCollection(
            normalizationContext: ['groups' => ['push_token:collection']],
            paginationEnabled: true
        ),
        new Post(denormalizationContext: ['groups' => ['push_token:write']]),
        new Delete()
    ],
    formats: ['jsonld', 'json']
)]
#[ApiFilter(SearchFilter::class, properties: ['token' => 'exact', 'user_id' => 'exact'])]
class PushToken extends Model
{
    protected $fillable = ['token', 'user_id', 'device_type'];

    #[Groups(['push_token:collection', 'push_token:read'])]
    public $id;

    #[Groups(['push_token:collection', 'push_token:read', 'push_token:write'])]
    public $token;

    #[Groups(['push_token:collection', 'push_token:read', 'push_token:write'])]
    public $user_id;

    #[Groups(['push_token:collection', 'push_token:read', 'push_token:write'])]
    public $device_type;

    #[Groups(['push_token:collection', 'push_token:read'])]
    public $created_at;
}

修改后的处理器示例

<?php

namespace App\Processor;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\Models\PushToken;
use Symfony\Component\Serializer\SerializerInterface;

class PushTokenCreateProcessor implements ProcessorInterface
{
    public function __construct(private readonly SerializerInterface $serializer) {}

    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = [])
    {
        /** @var PushToken $pushToken */
        $pushToken = $this->serializer->deserialize(
            json_encode($data),
            PushToken::class,
            'json',
            ['groups' => ['push_token:write']]
        );

        // 自定义逻辑:避免重复存储相同token
        $existingToken = PushToken::where('token', $pushToken->token)->first();
        if ($existingToken) {
            return $existingToken;
        }

        $pushToken->save();

        return $pushToken;
    }
}

内容的提问来源于stack exchange,提问作者Shahzaib Tariq Butt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 13:52:42