Generate JSON Feed với Laravel

JSON Feed là một tiêu chuẩn mới để formalize JSON dựa trên RSS feed nhằm đơn giản hóa việc tạo ra các feeds mà không phải dùng tới XML standard. Implement feed cho trang web của bạn đơn giản, và spec thực sự rõ ràng.

Đây là một ví dụ đơn giản của nó:

{
    "version": "https://jsonfeed.org/version/1",
    "title": "My Example Feed",
    "home_page_url": "https://example.org/",
    "feed_url": "https://example.org/feed.json",
    "items": [
        {
            "id": "2",
            "content_text": "This is a second item.",
            "url": "https://example.org/second-item"
        },
        {
            "id": "1",
            "content_html": "<p>Hello, world!</p>",
            "url": "https://example.org/initial-post"
        }
    ]
}

Tác giả của bài viết này cũng đã implemented định dạng feed này cho Laravel News, và bạn có thể thấy kết quả tại đây. Chúng ta sẽ làm một ví dụ nhanh để tạo ra một feed như thế này.

Lấy danh sách các posts

Bước đầu tiên là lấy một danh sách các bản ghi từ cơ sở dữ liệu. Đối với trang web này, các items được lưu trữ trong một bảng "Posts" và sử dụng Eloquent lấy ra 20 bản ghi mới nhất cho feed:

$posts = Post::limit(20)->get();

Thiết lập nguồn JSON Feed chính

JSON Feed spec có một số tuỳ chọn tại top level fields như title, feed URL, site icon, và hơn nữa. Những dữ liệu này thường không động và chúng ta phải thêm vào mảng này bằng tay như thế này:

$data = [
    'version' => 'https://jsonfeed.org/version/1',
    'title' => 'Laravel News Feed',
    'home_page_url' => 'https://laravel-news.com/',
    'feed_url' => 'https://laravel-news.com/feed/json',
    'icon' => 'https://laravel-news.com/apple-touch-icon.png',
    'favicon' => 'https://laravel-news.com/apple-touch-icon.png',
    'items' => [],
];

Mảng items rỗng ở trên sẽ chứa tất cả các posts của chúng ta.

Thêm các JSON Feed Items

Bước cuối cùng là lặp qua tất cả các $posts của chúng ta và thêm nó vào items aray. Đây là một ví dụ sử dụng dữ liệu của Laravel News:

foreach ($posts as $key => $post) {
    $data['items'][$key] = [
        'id' => $post->id,
        'title' => $post->title,
        'url' => 'https://laravel-news.com/'.$post->uri,
        'image' => $post->featured_image,
        'content_html' => $post->parsed_content,
        'date_published' => $post->created_at->tz('UTC')->toRfc3339String(),
        'date_modified' => $post->updated_at->tz('UTC')->toRfc3339String(),
        'author' => [
            'name' => $post->user->name
        ],
    ];
}

Một phần cần chú ý là timestamps. Chúng ta sử dụng tính năng của Carbon để convert sang UTC và sau đó sang RFC 3339 format mà JSON spec yêu cầu.

Kết quả cuối cùng

Đây là đoạn code đầy đủ của method json:

public function json()
{
    $posts = Post::active()->limit(20)->get();

    $data = [
        'version' => 'https://jsonfeed.org/version/1',
        'title' => 'Laravel News Feed',
        'home_page_url' => 'https://laravel-news.com/',
        'feed_url' => 'https://laravel-news.com/feed/json',
        'icon' => 'https://laravel-news.com/apple-touch-icon.png',
        'favicon' => 'https://laravel-news.com/apple-touch-icon.png',
        'items' => [],
    ];

    foreach ($posts as $key => $post) {
        $data['items'][$key] = [
            'id' => $post->id,
            'title' => $post->title,
            'url' => 'https://laravel-news.com/'.$post->uri,
            'image' => $post->featured_image,
            'content_html' => $post->parsed_content,
            'date_created' => $post->publishes_at->tz('UTC')->toRfc3339String(),
            'date_modified' => $post->updated_at->tz('UTC')->toRfc3339String(),
            'author' => [
                'name' => $post->user->name
            ],
        ];
    }
    return $data;
}

Một điều cần lưu ý là với Laravel chúng ta không phải đặt bất kỳ headers đặc biệt nào hay phải làm bất cứ điều gì. Chỉ cần trả lại mảng dữ liệu $data, và nó sẽ tự động được chuyển đổi sang JSON và có các headers phù hợp.

Nếu bạn muốn implement một package để làm điều này bạn có thể sử dụng LaravelJsonFeed của Mateus Guimarães.

Tham khảo