codeigniter 4 rest api 错误 501 显示动作未实现

codeigniter 4 rest api error 501 show action not implemented

我正在尝试使用基于 this article 的 CI 4 创建一个简单的 REST 服务器。这是我的代码:

app/Controllers/Barang.php

<?php 

namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;
use App\Models\Model_Barang;


class Barang extends ResourceController
{

    use ResponseTrait;

    // get multiple data
    public function index()
    {
        $apiModel = new Model_Barang();
        $data = $apiModel->orderBy('id', 'ASC')->findAll();
        return $this->respond($data);
    }

    // get single data
    public function getBarang($id = null)
    {
        $apiModel = new Model_Barang();
        $data = $apiModel->where('id', $id)->first();
        if($data){
            return $this->respond($data);
        }else{
            return $this->failNotFound('Barang tidak ditemukan.');
        }
    }

    // the other functions for create, update, delete

}

app/Models/Model_Barang.php

<?php 

namespace App\Models;
use CodeIgniter\Model;

class Model_Barang extends Model
{
    protected $table = 'barang';
    protected $primaryKey = 'id';
    protected $allowedFields = [
      'nama', 
      'harga',
      'jumlah',
      'kode_supplier'
    ];
}

当我在 URL http://localhost:8080/barang/ 上使用带有 GET 方法的 Postman 测试它时,它工作正常(它显示 barang table 中的所有数据),但是当我使用 http://localhost:8080/barang/1 它突然 returns 一个错误说

{
    "status": 501,
    "error": 501,
    "messages": {
        "error": "\"show\" action not implemented."
    }
}

我知道根据代码,我应该改用 http://localhost:8080/barang/getBarang/1,当我尝试使用 getBarang/ 时它确实有效..但那不是 RESTful?另外,文章说我可以使用不带 getBarang/ 的 url 来获取特定数据。我做错了什么吗?或者这只是 CI4 的缺点?

解释:

$routes->resource('barang');

Resource Routes

上面app/Config/Routes.php中的代码行等同于:

// Equivalent to the following auto-generated routes:

$routes->get('barang/new',             'Barang::new');
$routes->post('barang',                'Barang::create');
$routes->get('barang',                 'Barang::index');
$routes->get('barang/(:segment)',      'Barang::show/'); 
$routes->get('barang/(:segment)/edit', 'Barang::edit/');
$routes->put('barang/(:segment)',      'Barang::update/');
$routes->patch('barang/(:segment)',    'Barang::update/');
$routes->delete('barang/(:segment)',   'Barang::delete/');

postman中调用http://localhost:8080/barang/1对应这条路由匹配:

$routes->get('barang/(:segment)',      'Barang::show/');

'Barang::show/' 意味着 CodeIgniter 将尝试在传递 (:segment)Barang 控制器中调用 show(...) 方法,在您的情况下是 1作为第一个方法参数。

由于您的控制器 缺少 show(...) 方法,CodeIgniter 会报错如下:

{
    "status": 501,
    "error": 501,
    "messages": {
        "error": "\"show\" action not implemented."
    }
}

解决方案:

要解决此问题,您有 2 个 options/solutions。无论哪种解决方案满足您的需求,您都可以使用 GET http://localhost:8080/barang/1

在邮递员中 获取单个数据集

解决方案 1:

只需重命名控制器方法:

App\Controllers\Barang.php

而不是:

// ...
public function getBarang($id = null) ❌
// ...

使用这个:

// ...
public function show($id = null) ✅
// ...

解决方案 2:

如果出于某种原因您希望保留方法名称 getBarang(...) 以充当预期方法 show(...) 的等价物,请告知 $routes->resource(...); not到auto-createshow(...)方法路由定义,以后自己手动定义。即:

Limit the Routes Made

app/Config/Routes.php

而不是:

// ...
$routes->resource('barang'); ❌
// ...

使用这个:

// ...
$routes->resource('barang', ['except' => 'show']); ✅
$routes->get('barang/(:segment)',      'Barang::getBarang/');
// ...