Rumah > rangka kerja php > Laravel > Laravel melaksanakan pengembalian maklumat halaman tersuai dengan Sumber!

Laravel melaksanakan pengembalian maklumat halaman tersuai dengan Sumber!

藏色散人
Lepaskan: 2022-02-03 04:00:30
ke hadapan
3223 orang telah melayarinya

Laravel melaksanakan pengembalian maklumat halaman tersuai dengan Sumber!


Baru-baru ini menyerahkan idea kepada rangka kerja Laravel - tambah pengesanan kaedah maklumat penomboran tersuai dalam PaginatedResourceResponse supaya ia boleh dikeluarkan apabila menggunakan Resource kelas Apabila melihat maklumat, adalah sangat mudah untuk menyesuaikan maklumat paging.

Mengapa anda memerlukannya

Pada dasarnya saya membangunkan API. Pada hari-hari awal, saya selalu kembali secara langsung, tetapi kaedah ini kadangkala menyebabkan beberapa masalah dan menyusahkan untuk diselenggara Selain itu, selalunya perlu untuk menambah medan tersuai dan menyediakan data yang berbeza untuk tujuan yang berbeza yang saya gunakan Resource tentukan data yang dikembalikan. [Disyorkan: tutorial video laravel]

Menggunakan Resource sangat mudah dan boleh menjelaskan logiknya. Tetapi ia mempunyai kelemahan, iaitu, terdapat terlalu banyak maklumat penomboran. Untuk projek API, dalam kebanyakan kes, banyak medan dalam maklumat paging output lalai tidak diperlukan, dan kerana ia sering disambungkan kepada beberapa projek lama, format data lama perlu digunakan atau dibuat serasi Medan maklumat paging adalah agak berbeza, tidak ada cara untuk menggunakan maklumat paging yang dikembalikan secara lalai.

Saya tidak tahu bagaimana semua orang mengendalikan maklumat paging dalam situasi yang sama, tetapi sebelum itu, untuk mencapai matlamat, saya biasanya mempunyai dua kaedah Satu ialah menyesuaikan Response, di mana Maklumat data adalah ditakrifkan semula, dan yang kedua adalah untuk menyesuaikan semua Resource kelas yang berkaitan.

Saya tidak tahu banyak tentang lapisan bawah Laravel, dan saya tidak mahir dalam pembangunan rangka kerja abstrak, tetapi selepas melalui ini, saya mendapati bahawa perkara boleh menjadi lebih mudah Seperti yang saya jelaskan dalam PR, jika anda boleh Apabila membina maklumat paging dalam src/Illuminate/Http/Resources/Json/PaginatedResourceResponse.php, anda boleh menggunakan maklumat paging komponen yang sepadan dengan kelas Resource Kemudian anda tidak perlu menghabiskan banyak masa untuk menyesuaikan banyak kelas. Jadi saya menyerahkan idea ini kepada rangka kerja Laravel. Komit ini tidak diterima secara langsung pada mulanya, tetapi telah digabungkan selepas pelarasan Taylor dan dikeluarkan dalam v8.73.2.

Ini adalah kali pertama saya menyumbang kod kepada Laravel, dan ini juga kali pertama saya menyerahkan permintaan gabungan kepada pangkalan kod yang begitu besar Walaupun ia tidak diterima pakai secara langsung, hasilnya menarik cukuplah.

Contoh Penggunaan

Nah, izinkan saya memberikan contoh mudah tentang cara menggunakannya.

Output lalai

{  
    "data": [],
    "links": {
        "first": "http://cooman.cootab-v4.test/api/favicons?page=1",
        "last": "http://cooman.cootab-v4.test/api/favicons?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« 上一页",
                "active": false
            },
            {
                "url": "http://cooman.cootab-v4.test/api/favicons?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "下一页 »",
                "active": false
            }
        ],
        "path": "http://cooman.cootab-v4.test/api/favicons",
        "per_page": 15,
        "to": 5,
        "total": 5
    }}
Salin selepas log masuk

Ini ialah output maklumat paging oleh Laravel secara lalai. Sudah tentu, ini sudah cukup untuk menghadapi banyak senario . Tetapi kadang-kadang kita mendapat masalah kerananya. Kami memerlukan sedikit fleksibiliti.

Apabila menggunakan kelas ResourceCollection

Mari kita lihat logik asas dahulu!

Apabila ResourceCollection dikembalikan daripada pengawal, kaedah toResponsenya akhirnya akan dipanggil sebagai tindak balas. Kemudian anda boleh terus mencari kaedah ini dan lihat:

   /**
     * Create an HTTP response that represents the object.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function toResponse($request)
    {
        if ($this->resource instanceof AbstractPaginator || $this->resource instanceof AbstractCursorPaginator) {
            return $this->preparePaginatedResponse($request);
        }

        return parent::toResponse($request);
    }
Salin selepas log masuk

Lihat, jika sumber semasa ialah objek paging, ia akan mengalihkan tugas untuk memproses respons paging. Pandangan seterusnya:

    /**
     * Create a paginate-aware HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    protected function preparePaginatedResponse($request)
    {
        if ($this->preserveAllQueryParameters) {
            $this->resource->appends($request->query());
        } elseif (! is_null($this->queryParameters)) {
            $this->resource->appends($this->queryParameters);
        }

        return (new PaginatedResourceResponse($this))->toResponse($request);
    }
Salin selepas log masuk

Oh, ia telah dipindahkan ke PaginatedResourceResponse sekali lagi. Ini adalah kelas yang akhirnya perlu kami ubah suai Memandangkan kandungan toResponse terlalu panjang, saya tidak akan menyiarkannya Di sini, ia adalah Di sini kita mula membina data respons Sudah tentu, maklumat paging juga diproses di sini, tetapi ia mempunyai kaedah bebas. Kaedahnya ialah paginationInformation, iaitu logik sebelum menyerahkan PR:

/**
     * Add the pagination information to the response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function paginationInformation($request)
    {
        $paginated = $this->resource->resource->toArray();

        return [
            'links' => $this->paginationLinks($paginated),
            'meta' => $this->meta($paginated),
        ];
    }
Salin selepas log masuk

Jika anda berhati-hati, anda sepatutnya dapat berfikir bahawa $this->resource di sini sebenarnya adalah contoh di atas ResourceCollection. Maka resource ialah data senarai kami, yang merupakan contoh maklumat halaman. Oleh itu, mengapa kami tidak boleh memproses maklumat halaman dalam ResourceCollection? Sudah tentu, tetapi kami perlu menambah sesuatu, dan itulah idea yang saya serahkan.

Selepas menggabungkan PR, logiknya adalah seperti berikut:

/**
     * Add the pagination information to the response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function paginationInformation($request)
    {
        $paginated = $this->resource->resource->toArray();

        $default = [
            'links' => $this->paginationLinks($paginated),
            'meta' => $this->meta($paginated),
        ];

        if (method_exists($this->resource, 'paginationInformation')) {
            return $this->resource->paginationInformation($request, $paginated, $default);
        }

        return $default;
    }
Salin selepas log masuk

Kaedah pemprosesan yang sangat mudah Jika terdapat kaedah pembinaan maklumat paging tersuai dalam kelas sumber yang sepadan, gunakannya Saya sendiri, buat masa ini, ini sememangnya idea yang baik.

Pada ketika ini, cara untuk menyesuaikan maklumat halaman harus jelas. Iaitu untuk menambah kaedah ResourceCollection pada kelas paginationInformation anda yang sepadan, contohnya:

public function paginationInformation($request, $paginated, $default): array
    {
        return [
            'page' => $paginated['current_page'],
            'per_page' => $paginated['per_page'],
            'total' => $paginated['total'],
            'total_page' => $paginated['last_page'],
        ];
    }
Salin selepas log masuk
Salin selepas log masuk

这是自定义后的数据输出情况:

{
    "data": [],
    "page": 1,
    "per_page": 15,
    "total": 5,
    "total_page": 1}
Salin selepas log masuk

结果如我所愿。

使用 Resource 类时

我通常只喜欢定义一个 Resource 类来应对单个对象和列表的情况,这里主要关注如何处理列表数据的分页自定义。

在控制器中,我一般都是这样使用:

public function Index(){
    // ....
    return  SomeResource::collection($paginatedData);}
Salin selepas log masuk

再来看看 collection 方法里做了什么:

   /**
     * Create a new anonymous resource collection.
     *
     * @param  mixed  $resource
     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
     */
    public static function collection($resource)
    {
        return tap(new AnonymousResourceCollection($resource, static::class), function ($collection) {
            if (property_exists(static::class, 'preserveKeys')) {
                $collection->preserveKeys = (new static([]))->preserveKeys === true;
            }
        });
    }
Salin selepas log masuk

原来它把数据转给了 ResourceCollection,那么只需要将这个  AnonymousResourceCollection 做个自定义不就可以了。

总结

这是一个很小优化,但是很有用。

在此之前,如果想要随着 Resource 返回自定义分页信息,会比较麻烦,需要自定义很多东西,这样的方式,对老用户而言小菜一碟,但是对新手就可能是件棘手的问题。那么自此之后,无论是老用户还是新手这件事将变得易如反掌。只需要在对应的 ResourceCollection 类中添加 paginationInformation 方法,类似下面这样:

public function paginationInformation($request, $paginated, $default): array
    {
        return [
            'page' => $paginated['current_page'],
            'per_page' => $paginated['per_page'],
            'total' => $paginated['total'],
            'total_page' => $paginated['last_page'],
        ];
    }
Salin selepas log masuk
Salin selepas log masuk

不过,如果你使用的是 Resource::collection($pageData) 方式,那么还需要额外自定义一个 ResourceCollection 类,并重写对应 Resource 类的 collection 方法。

我通常会定义一个对应的基类,然后其它的都继承它。也可以做个 trait,然后共用。

最后

其实,这个想法我很早就想提交的,但是我一直比较犹豫,这到底是不是一个很大众的需求。不过我最后想明白了,这样做既然能为我节省大量重复且危险的工作,有那么多的开发者,总会有人需要的,所以我提交了,同时也是验证下我的想法到底是否可行,我的做法是否最优,结果当然是我学到了很多,比如写稍微复杂的测试用例。

另外,我想知道大家有没其它方法,或你们是怎么对待不同情况的分页信息的。

最后的最后,你如果也有好的想法,那么尽快提交吧!                                       

Atas ialah kandungan terperinci Laravel melaksanakan pengembalian maklumat halaman tersuai dengan Sumber!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:learnku.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan