Lumen rest api demo with Dingo/Api, JWT, CORS, PHPUNIT

Overview

lumen-api-demo

这是一个比较完整用 lumen 5.7 写的的 REST API 例子。使用了 dingo/api ,jwt 实现登录,功能上很简单,登录,注册,发帖,评论,单元测试(正在补充)。

StyleCI License donate donate

lumen5.x 请看对应的分支

有需要随时联系我

  • lumen/laravel/restful 交流群: 216721539 (备注 laravel 或 lumen)
  • email: [email protected]

ENGLISH README

教程

Laravel 教程 - 实战构架 API 服务器

USEFUL LINK

读文档很重要,请先仔细读读文档 laravel, dingo/api,jwt,fractal 的文档。

USAGE

$ git clone [email protected]:liyu001989/lumen-api-demo.git
$ composer install
$ 设置 `storage` 目录必须让服务器有写入权限。
$ cp .env.example .env
$ vim .env
    DB_*
        填写数据库相关配置 your database configuration
    JWT_SECRET
        php artisan jwt:secret
    APP_KEY
        lumen 取消了key:generate 所以随便找个地方生成一下吧
        md5(uniqid()),str_random(32) 之类的,或者用jwt:secret生成两个copy一下

$ php artisan migrate
$ php artisan db:seed (默认添加了10个用户,50篇帖子, 100条评论)

头信息中可以增加 Accept:application/vnd.lumen.v1+json 切换v1和v2版本

api文档在public/apidoc里面有一份,网络不好的可以直接查看本地的文档, 也可以看上面的 `项目api在线文档`

我是这样生成的: apidoc -i App/Http/Controllers/Api/V1/ -o public/apidoc/

如果访问一直不对,可以进入public 目录执行 php -S localhost:8000 -t public,然后尝试调用几个接口,从而确定是否为web服务器的配置问题。

REST API DESIGN

大概举个例子说明一下 rest api 吧

github 的 api 真的很有参考价值 github-rest-api

    例子: 用户,帖子,评论
    get    /api/posts              	 帖子列表
    post   /api/posts              	 创建帖子
    get    /api/posts/5            	 id为5的帖子详情
    put    /api/posts/5            	 替换帖子5的全部信息
    patch  /api/posts/5            	 修改部分帖子5的信息
    delete /api/posts/5            	 删除帖子5
    get    /api/posts/5/comments     帖子5的评论列表
    post   /api/posts/5/comments     添加评论
    get    /api/posts/5/comments/8   id为5的帖子的id为8的评论详情
    put    /api/posts/5/comments/8   替换帖子评论内容
    patch  /api/posts/5/comments/8   部分更新帖子评论
    delete /api/posts/5/comments/8   删除某个评论
    get    /api/users/4/posts        id为4的用户的帖子列表
    get    /api/user/posts           当前用户的帖子列表

    // 登录,刷新,登出
    // 或许可以有更好的命名
    post    /api/authorizations  创建一个token
    put     /api/authorizations/current  刷新当前 token
    delete  /api/authorizations/current  删除当前 token

问题总结

Lumne 和 Laravel 选哪个

首先建议大家使用 Laravel,参考超哥的答案 https://laravel-china.org/articles/5079/laravel-or-lumen。Laravel 提供了更全的功能,更容易使用,非常方便。Lumen 只是为了Api 而生,而我们通常的业务场景会是一套 Api 和一套后台管理系统,使用 Laravel 会让你更快更好的完成需求。非常非常不建议新手直接使用 Lumen。

jwt 使用

lumen 5.2 取消了session,没有了 auth 的实例,所以使用jwt的时候需要配置一下,注意 config/auth.php 中的配置,而且 user 的 model 需要实现 Tymon\JWTAuth\Contracts\JWTSubject;

基本用法, jwt 会 encode 对应模型的 id,生成token,客户端拿到 token,放在 Authorization header 中

Authorization: Bearer token

验证的逻辑就是 decode token 拿到id,然后找到对应的用户。当然了,你可能需要 encode 额外的字段,那么可以使用 CustomClaims。

token 有两个时间,一个是过期时间(ttl),一个是可刷新时间(refresh_ttl)。怎么理解,比如 ttl 是 1 天,refresh_ttl 是1周,那么 token 一天后过期,但是1周之内你仍然可以用这个 token 换取一个新的 token,而这个新 token 又会在 1 天后过期,1周内可刷新。

举个例子,用户登录了你的应用,并且每天都会打开你的应用,你的应用如果发现这个 token 过期了,会主动刷新一次,如果成功那么用户依然是登录的。当用户1周都没有登录过你的应用,那么他就需要重新登录了。

客户端的逻辑应该是,首先判断这个 token 是否过期了,1是通过两个 ttl 判断,因为客户端是知道这两个时间的,2是调用需要授权的接口返回的状态码(401),判断过期了则主动尝试刷新,刷新成功了,重置token和时间,失败了,则跳转到登录页面。

使用mail

写了个例子,注册之后给用户发送邮件, 可以参考一下。

  • composer 加 illuminate/mail 和 guzzlehttp/guzzle 这两个库
  • 在 bootstrap/app.php 或者 provider 中注册 mail 服务
  • 增加配置 mail 和 services, 从 laravel 项目里面 cp 过来
  • 在 env 中增加 MAIL_DRIVER,账户,密码等配置
transformer 的正确使用

transformer 是个数据转换层,帮助你格式化资源。还可以帮助你处理资源之间的引用关系。

试着体会一下以下几个url的也许就明白了

是不是很强大,我们只需要提供资源,及资源之间的引用关系,省了多少事

transformer 如何自定义格式化资源

dingo/api 使用了 Fractal 做数据转换,fractal 提供了3种基础的序列化格式,Array,DataArray,JsonApi,在这里有详细的说明 http://fractal.thephpleague.com/serializers/。DataArray 是默认的,也就是所有资源一定有data和meta。当然也可以按下面这样自定义:

    只需要在 bootstrap/app.php 中设置 serializer 就行了。具体见 bootstrap/app.php 有注释
    $app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
        $fractal = new League\Fractal\Manager;
        // 自定义的和fractal提供的
        // $serializer = new League\Fractal\Serializer\JsonApiSerializer();
        $serializer = new League\Fractal\Serializer\ArraySerializer();
        // $serializer = new App\Serializers\NoDataArraySerializer();
        $fractal->setSerializer($serializer);,
        return new Dingo\Api\Transformer\Adapter\Fractal($fractal);
    });

个人认为默认的 DataArray 就很好用了,基本满足了 API 的需求

422 错误提示

参考了 github 的错误提示,这样可能更方便 app 对接,格式固定有field 和code,field为字段名,code为错误提示。

如果想用默认的,在 BaseController 中使用下面的代码即可 throw new ValidationHttpException($validator->errors());

TODO

  • 单元测试

License

MIT license

Comments
  • 请教一个在lumen+dingo+jwt+laravel_wechat的环境下的问题

    请教一个在lumen+dingo+jwt+laravel_wechat的环境下的问题

    在验证微信服务器的时候,提示: ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Call to undefined method Symfony\Component\HttpFoundation\Response::header() 我知道可能是dingo response的问题,我想自定义一个controller不使用dingo的response或者是不使用dingo的middleware,但是我是菜鸟,花了很长时间还是没有弄好, 请您看下是怎么回事

    opened by mentallxm 17
  • meta

    meta

    meta中的links格式问题,如果links为空,返回一个空数组,反之返回一个对象,这种数据不一致的情况算bug吗?具体源码出在这里\vendor\league\fractal\src\Serializer\ArraySerializer.php, $pagination['links'] = [];

        if ($currentPage > 1) {
            $pagination['links']['previous'] = $paginator->getUrl($currentPage - 1);
        }
    
        if ($currentPage < $lastPage) {
            $pagination['links']['next'] = $paginator->getUrl($currentPage + 1);
        }
    

    这里如果 $pagination['links'] 没有值的情况下,直接就输入出了初始化的这个[]

    opened by yangzuwei 9
  • 安装好了,但是报一个错。

    安装好了,但是报一个错。

    http://lumen.jmqu.cn/auth/register post email:[email protected] password:xxxx { "message": "Declaration of ApiDemo\Repositories\Eloquent\BaseRepository::update() must be compatible with ApiDemo\Repositories\Contracts\RepositoryInterface::update(ApiDemo\Repositories\Contracts\int $id, array $attributes)", "code": 64, "status_code": 500 } 报这个错是什么原因?

    opened by bencen 9
  • 请教一个关于dingo api的问题

    请教一个关于dingo api的问题

    您好,请问如何能统一dingo api返回的异常处理结构,现在一旦报异常,就只有messaage和status_code2个字段;比如我用laravel5.4的用户授权中,采用Policy方式,在路由中加can:update,**,来验证授权,一旦授权不允许,会返回 { "message": "This action is unauthorized.", "status_code": 500 }

    我想自定义这个结构。

    opened by huantu284 8
  • need authentication的情况下,发送带有token的header,会返回The Response content must be a string or object implementing __toString(), \

    need authentication的情况下,发送带有token的header,会返回The Response content must be a string or object implementing __toString(), \"boolean\" given.

    在本地调试的,不知道怎么回事,重新下载最新版,全新安装的也是这种情况 php version 5.6.27 + apache 我测试了https://lumen.lyyw.info/api/user 没有返回这个错误,请帮助看下,多谢 流程: 1.通过https://lumen.lyyw.info/api/users,post用户,得到token 2.通过https://lumen.lyyw.info/api/user header里面Authorization为:Bearer {token} 流程应该是没有问题的,用的postman调试的

    opened by yumanchao 4
  • 请问Transformer里面的includeUser怎样使用啊?

    请问Transformer里面的includeUser怎样使用啊?

    我现在是这样子手动加载使用。我看见你的demo里面没有其他关于includeUser调用的代码。自己尝试了很久也没发现可以自动加载的。

    return $this->response()
                ->paginator($articles, (new ArticleTransformer)->setDefaultIncludes(['user']));
    
    opened by PonyTang3 3
  • 接口是使用policy ,报错  “This action is unauthorized”

    接口是使用policy ,报错 “This action is unauthorized”

    //policy中修改资源的权限 UserOriResPolicy public function update(User $user,UserOriFiles $userOriFiles){ return $user->uid === $userOriFiles->author_id; }

    // controller中的方法 public function update($id){ //侧路模式的权限判断

    	$userOriFile = UserOriFiles::find($id);
    	$isok = $this->authorize('update',$userOriFile);
    

    最后接口一直报错 “This action is unauthorized”, google 上有这个问题,但没有回答,你有在项目中用到Policy 吗?

    https://www.laracasts.com/discuss/channels/laravel/laravel-54-policies-not-working-with-jwt

    opened by cmming 2
  • wrong assignment in base repo

    wrong assignment in base repo

    file: app/Repositories/Eloquent/BaseRepository.php

    public function where(array $data)
    {
        $this->model = $this->model->where($data);
        return $this;
    }
    

    $model->where() will call the magic method __call, and get the new instance of '\Illuminate\Database\Eloquent\Builder' rather than the '\Illuminate\Database\Eloquent\Model'

    opened by xuzc 2
  • Using Session inside Lumen

    Using Session inside Lumen

    First thing, thank you to create this very useful demo API in Lumen.

    I have a question related to work around using PHP session in Lumen 5.2 and 5.3. I know it's removed in these version. Just wonder if you have any advice if I want to use Session.

    Again thank you very much

    opened by anhphamt 2
  • Do you have an English version?

    Do you have an English version?

    Hi Yu Li, I don't know the best way to contact you. Do you consider writing this in English? Also do you have an English version of this -> http://oomusou.io/laravel/laravel-architecture/

    opened by geocine 2
  • 项目没部署成功

    项目没部署成功

    ➜ ~ homestead edit - map: h.lumen-api-demo to: /home/vagrant/Code/lumen-api-demo/public

    /etc/hosts:

      127.0.0.1 h.luemn-api-demo
    

    vagrant halt vagrant up -provision

    ➜ ~ curl http://h.lumen-api-demo:8000/api/auth/signin curl: (6) Could not resolve host: h.lumen-api-demo

    opened by ghost 2
  • Auth driver [jwt] for guard [api] is not defined.

    Auth driver [jwt] for guard [api] is not defined.

    app.php中把这个注释打开后报错,不太清楚这个逻辑,请问能讲下吗。 app('Dingo\Api\Auth\Auth')->extend('jwt', function ($app) { return new Dingo\Api\Auth\Provider\JWT($app['Tymon\JWTAuth\JWTAuth']); });

    opened by balabalab 1
  • 数据库无法连接?

    数据库无法连接?

    In Connection.php line 664:

    could not find driver (SQL: select * from information_schema.tables where table_schema = chat and table _name = migrations)

    In Connector.php line 67:

    could not find driver

    opened by ityc 0
  • cors功能貌似有问题

    cors功能貌似有问题

    1. clone当前节点上的代码,composer install(删除掉vendor先)
    2. 跨域的时候cors不生效,但是放到$app->middleware后生效。
    $app->middleware([
        // 根据 accept-language 设置语言
        'locale' => App\Http\Middleware\ChangeLocale::class,
        'cors' => palanik\lumen\Middleware\LumenCors::class,
    ]);
    
    $app->routeMiddleware([
        //'cors' => palanik\lumen\Middleware\LumenCors::class,
        'auth' => App\Http\Middleware\Authenticate::class,
        'serializer' => \Liyu\Dingo\SerializerSwitch::class,
    ]);
    
    1. 另外这个第三放组件不管啥options请求都劫持并返回肯定是不好的。
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next) {
    
            if ($request->isMethod('OPTIONS')) {
                $response = new Response("", 200);
            }
            else {
                $response = $next($request);
            }
    
    opened by wgqi1126 1
Proyecto Start-Basic sobre Login y crud de usuarios, mediante Api Rest, usando la plantilla AdminLte 3.1 y manejo de roles y permisos con spatie y autenticacion JWT

Proyecto Start-Basic sobre Login y crud de usuarios, mediante Api Rest, usando la plantilla AdminLte 3.1 y manejo de roles y permisos con spatie y autenticacion JWT

null 9 Jul 5, 2022
Slim Jam is a demo application to provide examples for composer package, PHPSpreadsheet, Shopify API etc. usages.

SLIM JAM Slim Jam is a demo application to provide examples for composer package, PHPSpreadsheet, Shopify API etc. usages. This project aims to take a

Uğur ARICI 2 Jan 9, 2022
Laravel & Hasura Demo

Laravel & Hasura Demo

Rob Mellett 2 Oct 4, 2021
Laravel Datatables Package Demo App

#Laravel Datatables Demo App Datatables Package for Laravel 4|5 This package is created to handle server-side works of DataTables jQuery Plugin via AJ

Arjay Angeles 139 Dec 23, 2022
The best squirrel tracker. Ever. (A demo app for LaravelSF meetups)

LaraSqrrl Identify and track squirrels via text, now using AWS Rekognition! Created for the November 10th, 2015; February 9th, 2016; May 10th, 2016; a

Paul Foryt 3 Mar 29, 2022
Repository with demo for "Sextou"

Newsletter Demo APP Beer & Code Newsletter Page for newsletter. ?? About this repository Demo App Demo APP for the talks at Beer and Code Youtube chan

Beer And Code 4 Feb 5, 2022
Menu ordering/management application demo, like Wordpress menu manager

Menu manager like Wordpress using Laravel and Nestable See demo at: http://laravel-menu-builder.gopagoda.com/admin/menu Tutorial coming up at: http://

Maksim Surguy 336 Nov 25, 2022
This is an open source demo of administration panel for polymorphic relationship and SEO content

Laravel SEO admin This application demonstrates usage of polymorphic relationships described at (http://maxoffsky.com/code-blog/using-polymorphic-rela

Maksim Surguy 127 Oct 11, 2022
A Laravel 8 and Livewire 2 demo showing how to search and filter by tags, showing article and video counts for each tag (Polymorphic relationship)

Advanced search and filter with Laravel and Livewire A demo app using Laravel 8 and Livewire 2 showing how to implement a list of articles and tags, v

Sérgio Jardim 19 Aug 29, 2022
Laravel Real-time chat app demo with React, Laravel Echo, Breeze, Socket.io, Redis, Inertia.js, TailwindCSS stack.

Laravel Real-time Chat App You can build yours from scratch with the following Medium article https://medium.com/@sinan.bekar/build-a-real-time-chat-a

Sinan Bekar 9 Oct 3, 2022
A demo of how to use filament/forms to build a user-facing Form Builder which stores fields in JSON.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Dan Harrin 41 Dec 24, 2022
Public API for the project coding.events. Made in PHP 8.0 with Lumen 8, PHP-FPM, NGINX and MySQL 8.

coding.events API Uma API feita apenas para passar o tempo, montando uma API para o site <coding.events>. Sinta-se livre para usar esse código como es

Kaique Garcia 3 Oct 9, 2022
Laravel Responder - a package for building API responses, integrating Fractal into Laravel and Lumen

A Laravel Fractal package for building API responses, giving you the power of Fractal with Laravel's elegancy.

Alexander Tømmerås 776 Dec 25, 2022
create API-LUMEN

Lumen PHP Framework Laravel Lumen is a stunningly fast PHP micro-framework for building web applications with expressive, elegant syntax. We believe d

L. Yasril Imam 3 Nov 25, 2022
The fastest way to make a powerful JSON:API compatible Rest API with Laravel.

The first fully customizable Laravel JSON:API builder. "CRUD" and protect your resources with 0 (zero) extra line of code. Installation You can instal

BinarCode 288 Aug 8, 2022
Teste dos mano do pay lá ft. Lumen Framework

Teste dos caras lá pay Avisos antes de começar Crie um repositório no seu GitHub sem citar nada relacionado a empresa dos cara lá. (CHECK) Faça seus c

Daniel Reis 24 Nov 7, 2022
📦 Adds Laravel Packages Support to Lumen and Vendor Publish Artisan Command.

Laravel Package Support for Lumen: Makes Lumen compatible with Laravel Packages. You can use any Laravel Packages in Lumen by installing Larasupport Package.

Irfaq Syed 127 Dec 17, 2022
A collection of generators for Lumen and Laravel 5.

Lumen generators A collection of generators for Lumen and Laravel 5. Contents Why ? Installation Quick Usage Detailed Usage Model Generator Migration

Amine Ben hammou 349 Mar 24, 2022
A Laravel and Lumen Badges Generator

Laravel and Lumen Badge Generator That package is a easy wrapper to Badges/Poser. #Installing composer require vluzrmos/laravel-badge-poser Laravel co

Vagner Luz do Carmo 6 Jun 10, 2020