Dingo API 初探
打赏作者

woailuosj

@JellyBool 为什么我路由写了访问会出现两个\?

"message":"Class App\\Api\\Controllers\\ValidController does not exist","code":-1,"status_code":500,"debug

路由是这样写得:

$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
    $api->group(['namespace' => 'App\Api\Controllers'], function ($api) {
        $api->get('onephone', 'ValidController@onephone');
        $api->get('oneidentity', 'ValidController@oneidentity');
    });
});

是不是用dingo/API不能用php artisan server?

woailuosj
"message": "Target [App\\Http\\Requests\\Request] is not instantiable.",

怎么在自己新建的Api/Controllers里获取请求?

JellyBool

也是可以使用request的啊。视频应该就有的啊 @woailuosj

woailuosj

@JellyBool 哦,好的,在下一个视频看到了,应该导入的是
use Illuminate\Http\Request;
我搞成
App\Http\Request里,谢谢

xudong0226

hi ,@JellyBool
1.保证低、高版本API可以兼容使用

有没有更好的写法?

  1. .evn 配置文件中
    API_VERSION=v1
    怎么理解?
JellyBool

嗯,有一种解决方法是在header当中提供api版本的信息,比如:

$version = Request::header('api-version');

我们可以要求用户提供这个api-version的header,如果没有提供,则取默认版本。然后可以根据用户提供的header来进行版本判断,类似于这样:

$version = Request::header('api-version');
(isset($version)) ? Route::resource('user', 'v{$version}\UserController'); : Route::resource('user', 'v2\UserController');

当然,上面都是举例,你可以根据自己的实际业务需求来判断。 @xudong0226

后面视频中使用dingo/api的时候会方便很多:

$api->version(['v1', 'v2'], function ($api) {

});
wl876645

如果User表hasmany了其他的表。在Transformers和UserController里有实现的办法吗?谢谢大神!

JellyBool 回复 wl876645

你具体需要实现什么需求呢?

public function transform ($user) {
    return [
             // 其他的
            'posts' => $user->posts
     ];
}

这样?

wl876645

不好意思我傻逼了,我解决了

nater 回复 wl876645

怎么解决的?

changyibo

大哥,你光说复制两行,你是从哪里复制的呀,每次敲着都很不爽的…

iralance

Call to undefined method Illuminate\Routing\Route::getUri()
路由那边设置不成功

JellyBool 回复 iralance

估计是 laravel 版本的问题,或者你仔细看一下

iralance 回复 JellyBool

奥。应该是版本问题了。我laravel 5.3的版本了。

lg23

“tymon/jwt-auth”: "1.0.0-beta.2"
这个版本同群主所说的版本具体会有些什么区别

JellyBool 回复 lg23

你去看看它的 release 有没有重大的说明,不然应该没有大的区别

lg23

collection 这个方法哪来了,视频中没看到

kenn

这是laravel5.* 版本的,具体是哪个版本啊,我写到后面发现我的路由在一个单独的routes文件中,我用的laravel5.4

JellyBool 回复 kenn

视频用的是 5.1 LTS 版本

supperTony

jelly,我查看路由的时候报这个错误php artisan route:list

错误如下:
A session had already been started - ignoring session_start()

实在找不到原因

JellyBool 回复 supperTony

你在你的代码的某个部分自己写了 session_start 吧。。。。

supperTony 回复 JellyBool

有可能与其他的包冲突么,php artisan route:list 的时候加载在路由后面的程序报错了,但是访问api的路由显示not found,其他路由没问题

JellyBool 回复 supperTony

有可能与其他的包冲突么?

你确定没有自己写 session_start() ? 那有可能是其他的 package 引入的

2.后面的问题描述清楚一点呗

supperTony 回复 JellyBool

已经找到session_start()所在,只是在打这个命令,php artisan route:list 的时候出错,访问路由是没有问题的,api的路由也能访问了

supperTony 回复 JellyBool

$api = app(‘Dingo\Api\Routing\Router’);

api>version(v1,function(api->version('v1',function(api){
api>group([namespace=>App\Api\Controllers],function(api->group(['namespace'=>'App\Api\Controllers'],function(api){
$api->get(‘news’,‘NewsController@index’);
});
});

supperTony

@JellyBool

return $this->response->error(‘啊送扽啊’,500);

中文返回格式问题
"message": “The Response content must be a string or object implementing __toString(), “boolean” given.”,
“status_code”: 500,

JellyBool 回复 supperTony

基本上是哪里写错了吧……

你返回了一个 bool 值

supperTony 回复 JellyBool

我找到原因了,文件是gbk的,改成utf-8就不会报错了

PHPclown

JellyBool好~ 当我做到最后字段映射的时候出现这样的错误
"message": “Argument 1 passed to App\Api\Transformers\LessonTransformer::transform() must be an instance of App\Api\Transformers\Lesson, instance of App\Lesson given, called in D:\xampp\htdocs\laravistapi\vendor\league\fractal\src\Scope.php on line 373 and defined”,
“status_code”: 500,
“debug”: {
“line”: 9,
“file”: “D:\xampp\htdocs\laravistapi\app\Api\Transformers\LessonTransformer.php”,
“class”: “ErrorException”,
“trace”: [

JellyBool 回复 PHPclown

命名空间写对应该就好了

PHPclown 回复 JellyBool

检查了很多遍,还是没发现写错的地方:

$lesson['title'], 'content' => $lesson['body'], 'is_free' => (boolean) $lesson['free'] ]; } } ?> collection($lessons,new LessonTransformer()); } } ?>
JellyBool 回复 PHPclown

App\Lesson 这个应该是 App\Api\Lesson ,要不然就是 api 那边的 Lesson 注入命名空间错了

PHPclown 回复 JellyBool

不好意思JellyBool,按照你说的还是没法解决,我写在有道笔记里,麻烦你了 http://note.youdao.com/noteshare?id=cf9cfe7c7f900c6f90ee0d5048fbdd34

JellyBool 回复 PHPclown

你的 LessonTransformer ,use App\Lesson;

以后代码用 markdown 排版一下吧
https://www.laravist.com/discuss/markdown/learn-to-use-markdown-21

PHPclown 回复 JellyBool

谢谢~ 好的

beaplat-61f

发现用了Transform返回的json就多了个’data’的key,可以去掉的吗

nanibigoo

laravel 5.4 安装jwt 需要版本1.0.x-dev

北漂张小白
class LessonsController extends BaseController
{
    public function index(){
        $lessons = Lesson::all();
        return $this->collection($lessons, new LessonTransformer());
    }
}

最后这个collection 是调用的那里的方法?
还有new LessonTransformer() 虽然实例化了但是 什么时候调用的transform()这个函数呢??

JellyBool 回复 北漂张小白

Dingo api 的 collection 方法。LessonTransformer 实例化之后,会去找 transform() 这个方法

JoouA 回复 JellyBool

老师 这个transform()的方法名是要固定的写成transform的吗,还是随意写方法名的 实例化之后最终都会去找这个方法

JellyBool 回复 JoouA

transform 这个方法名当然是随便你定义的。

如果你使用 dingo api 等一些 package,这些package通常会定义一些方法名字需要你遵守

carsonlius 回复 JellyBool
  • transform 方法名称不是随便定义的吧
  • abstract class TransformerAbstract的介绍
/**
 * Transformer Abstract
 *
 * All Transformer classes should extend this to utilize the convenience methods
 * collection() and item(), and make the self::$availableIncludes property available.
 * Extend it and add a `transform()` method to transform any default or included data
 * into a basic array.
 */
Ruanjun

1.你好请问我这里配置的时候出现了一个小问题,我用的是laravel5.4,当我用php artisan api:routes查看的时候提示我

PHP Fatal error:  Call to undefined method Closure::__set_state() in D:\phpStudy\WWW\laravel-api\bootstrap\cache\config.php on line 27
PHP Stack trace:
PHP   1. {main}() D:\phpStudy\WWW\laravel-api\artisan:0
PHP   2. Illuminate\Foundation\Console\Kernel->handle() D:\phpStudy\WWW\laravel-api\artisan:36
PHP   3. Illuminate\Foundation\Console\Kernel->bootstrap() D:\phpStudy\WWW\laravel-api\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:114
PHP   4. Illuminate\Foundation\Application->bootstrapWith() D:\phpStudy\WWW\laravel-api\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:267
PHP   5. Illuminate\Foundation\Bootstrap\LoadConfiguration->bootstrap() D:\phpStudy\WWW\laravel-api\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:208
PHP   6. require() D:\phpStudy\WWW\laravel-api\vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\LoadConfiguration.php:28

2.在bootstrap的cache的config.php中的27行

'auth' => 
    array (
      'basic' => 
      Closure::__set_state(array(
      )),
      'jwt' => 
      Closure::__set_state(array(
      )),
    ),
JellyBool 回复 Ruanjun

5.4 的时候,配置文件貌似不支持 Closure Function 的形式了

Ruanjun 回复 JellyBool

请问我该怎么修改

JellyBool 回复 Ruanjun

你看最新的文档说明,应该有兼容到版本的说明

JellyBool 回复 Ruanjun

基本上就是就该配置文件了:

'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,

都改成这种 class 的形式

hate

难道用laravel 就是用各种插件吗

JellyBool 回复 hate

你也可以自己写的啊,这些 package 只不过是封装好了的

hate 回复 JellyBool

我学到现在,很多东西都会,但是自己做不出来,矛盾

JellyBool 回复 hate

就是写得太少而已

hate 回复 JellyBool

也是,猛写3遍

hate 回复 JellyBool

应用场景啊,就个那个laravel社区能自己做出来

zhenzihui

5.5版本已经有专门的api路由了,还需要dingo吗?

JellyBool 回复 zhenzihui

我觉得不用啊

zhenzihui 回复 JellyBool

好吧,还有个问题,用户认证用passport的话,前端是只能用Vue还是安卓/ios等都支持?

JellyBool 回复 zhenzihui

你只要能获取到 token 就好了啊,前端用什么没什么关系

zhenzihui 回复 JellyBool

好,谢谢大佬

carsonlius 回复 JellyBool

什么意思? laravel5.5之后 dingo/api 这个package就没有意义了吗?

JoouA

老师
class LessonsController extends BaseController
{
public function index()
{
$lessons = Lesson::all();

    return $this->collection($lessons,new LessonTransformer());

}

里面的$this->collection() 这个collection方法是属于哪一个类的啊,我在BaseController里面也没有找到呢

JoouA

Dingo api 的 collection 方法。LessonTransformer 实例化之后,会去找 transform() 这个方法

yjx496844026

GET|HEAD | /api // 前缀/lessons | | App\Api\Controllers\LessonsController@index 为什么我的uRL 带了前缀两个字

JellyBool 回复 yjx496844026

额。你的 env 的配置项看看是不是有前缀

y7ut123
class TwitterTransformer extends TransformerAbstract
    {
        protected $availableIncludes = ['twitterpic','consumer'];
    
        public function transform(Twitter $twitter)
        {
            return $twitter->attributesToArray();
        }
    
        public function includeConsumer(Twitter $twitter){
            if (! ($twitter->consumer)) {
                return $this->null();
            }
    
            return $this->item($twitter->consumer, new TwitterConsumerTransformer());
        }
        public function includeTwitterpicr(Twitter $twitter)
        {
            if (! $twitter->twitterpics) {
                return $this->null();
            }
    
            return $this->item($twitter->twitterpics, new TwitterpicTransformer());
        }
    
    }

TwitterpicTransforms.php

    use App\Twitterpic;
    use League\Fractal\TransformerAbstract;
    
    class TwitterpicTransformer extends TransformerAbstract
    {
    
        public function transform(Twitterpic $twitterpic){
    
            return
                [
                    'id'=>$twitterpic['id'],
                    'image_url'=>$twitterpic['pic'],
    
                ];
        }
    }

单结果中 include 的字段为何还是无法加载,困扰了一下午,我照着文档看了好多遍。。。没毛病啊

{
    "data": [
        {
            "id": 4,
            "content": "A et suscipit est sed.",
            "clubname": "Dr. Duane Emard III",
            "club_id": 17,
            "consumer_id": 10,
            "likes": 0,
            "created_at": "2017-08-26 08:12:05",
            "updated_at": "2017-08-26 08:12:05"
        },
        {
            "id": 5,
            "content": "Tempora nesciunt et delectus cumque eos et architecto.",
            "clubname": "Patsy Rutherford",
            "club_id": 1,
            "consumer_id": 6,
            "likes": 0,
            "created_at": "2017-08-26 08:12:05",
            "updated_at": "2017-08-26 08:12:05"
        }
    ]
 }
JellyBool 回复 y7ut123

你用的是 dingo api 还是什么?具体版本是多少?

y7ut123 回复 JellyBool

就是dingo api laravel 5.4

JellyBool 回复 y7ut123

includeTwitterpicr 这个原因?

y7ut123 回复 JellyBool

…这个不是,这是我复制时候不小心摁上的r,我不管换什么字段都,没有include成功

JellyBool 回复 y7ut123

我看了一下 dingo 的文档,貌似没有找到 include 的用法,可否给个链接?

JellyBool 回复 y7ut123

你请求的 url 是怎么样的?有触发类似下面的代码?

$fractal = new Fractal\Manager();

if (isset($_GET['include'])) {
    $fractal->parseIncludes($_GET['include']);
}
y7ut123 回复 JellyBool

请求了啊。不过每次都要include 我就换成了defaultinclude…我还在研究 哎弄了一天了

JellyBool 回复 y7ut123

那这个我也看不出来什么错了。。。

y7ut123 回复 JellyBool

知道原因了

return this>item(this->item(twitter->twitterpics, new TwitterpicTransformer());

其中item必须传入的是一个单独的model类,不可以是集合 如果传入集合 必须是 collection 而我的twitter 中的 是一个集合 我只取 没个twitter的第一个pic 就可以使用item 来 transform 了 哈哈哈哈

wdgwgz

执行:php artisan api:routes

报错:
[BadMethodCallException]
Method getUri does not exist.

JellyBool 回复 wdgwgz

总感觉这种要不就是版本没对,要不就是代码没下载完

wdgwgz 回复 JellyBool

解决了,根据Github issues的回答,更新到Dingo1.0 beta8版本就可以了

wdgwgz 回复 JellyBool

但是现在遇到一个新问题,api.php代码如下:

$api = app('Dingo\Api\Routing\Router');

$api->version('v1', function ($api) {
    $api->group(['namespace'=>'App\Api\Controllers'],function ($api){

        $api->get('lessons','LessonsController@index');

    });
});

执行:php artisan api:routes
结果:Your application doesn’t have any routes.

是因为我的Laravel版本是5.5的原因吗?

JellyBool 回复 wdgwgz

嗯,有可能是。如果用 5.5 的话。直接用 Resource 就好

wdgwgz

昨天Dingo、JWT在服务器中终于安装好了,Dingo定义的路由也可以访问了,然后今天git clone到homestead环境下,修改.env数据库信息,执行composer update 、 php artisan migrate。访问默认首页(Laravel自带)正常,访问Dingo定义的路由却报:NotFoundHttpException

具体报错如下:

(1/1) NotFoundHttpException
in RouteCollection.php (line 179)
at RouteCollection->match(object(Request))
in Router.php (line 548)
at Router->findRoute(object(Request))
in Router.php (line 527)
at Router->dispatchToRoute(object(Request))
in Router.php (line 513)
at Router->dispatch(object(Request))
in Kernel.php (line 174)
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
in Pipeline.php (line 30)
at Pipeline->Illuminate\Routing\{closure}(object(Request))
in TransformsRequest.php (line 30)
at TransformsRequest->handle(object(Request), object(Closure))
in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))
in TransformsRequest.php (line 30)
at TransformsRequest->handle(object(Request), object(Closure))
in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))
in ValidatePostSize.php (line 27)
at ValidatePostSize->handle(object(Request), object(Closure))
in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))
in CheckForMaintenanceMode.php (line 46)
at CheckForMaintenanceMode->handle(object(Request), object(Closure))
in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))
in Pipeline.php (line 102)
at Pipeline->then(object(Closure))
in Kernel.php (line 149)
at Kernel->sendRequestThroughRouter(object(Request))
in Kernel.php (line 116)
at Kernel->handle(object(Request))
in index.php (line 53)
JellyBool 回复 wdgwgz

NotFoundHttpException 这个报错就是路由没注册上呗

wdgwgz

transform哪些场景下用 哪些场景下不用呢?
不需要修改表字段名的地方就不使用吗?
可是我在github看到好多项目transform都是不修改字段名或者值的,比如这个transform 有啥意义呢?

Alt text

JellyBool 回复 wdgwgz

这些都是开源作者偷懒吧,这样做也 OK。但是也明白一点是,即使是这样:Transformer 这一层还是很有意义的,想象这样一个场景:如果说你没有这个 Transformer,直接用的数据库字段的话,万一某一天你需要修改你的数据库字段,这个时候难道你要通知所有的 API 使用者去改他们代码中的 API 字段么?

banyungong

这里的两个transform里的方法都是一样的,为什么要写两个transfrom,共用一个不就好了?

Flourishing

Laravel5.6 并没有遇见你们的坑… 很顺畅!

行觉 回复 Flourishing

laravel5.6不能生成key