├── .editorconfig
├── .env.ci
├── .env.example
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── dependabot.yml
└── workflows
│ └── test.yml
├── .gitignore
├── .php_cs.dist
├── .styleci.yml
├── LICENSE
├── README.md
├── app
├── Console
│ ├── Commands
│ │ └── .gitkeep
│ └── Kernel.php
├── Enums
│ └── ResponseCode.php
├── Events
│ ├── Event.php
│ └── ExampleEvent.php
├── Exceptions
│ └── Handler.php
├── Http
│ ├── Controllers
│ │ ├── AuthController.php
│ │ ├── Controller.php
│ │ └── UsersController.php
│ ├── Middleware
│ │ └── Authenticate.php
│ └── Resources
│ │ └── UserResource.php
├── Jobs
│ ├── ExampleJob.php
│ └── Job.php
├── Listeners
│ └── ExampleListener.php
├── Models
│ └── User.php
├── Providers
│ ├── AppServiceProvider.php
│ ├── AuthServiceProvider.php
│ └── EventServiceProvider.php
├── Services
│ └── UserService.php
└── Support
│ ├── Traits
│ ├── Helpers.php
│ └── SerializeDate.php
│ └── helpers.php
├── artisan
├── bootstrap
└── app.php
├── composer.json
├── composer.lock
├── config
├── app.php
├── auth.php
└── response.php
├── database
├── database.sqlite
├── factories
│ ├── PostFactory.php
│ └── UserFactory.php
├── migrations
│ ├── .gitkeep
│ ├── 2020_05_30_115810_create_users_table.php
│ └── 2020_10_16_105234_create_posts_table.php
└── seeders
│ ├── DatabaseSeeder.php
│ └── UsersSeeder.php
├── phpunit.xml
├── public
├── .htaccess
└── index.php
├── resources
├── lang
│ └── zh_CN
│ │ └── enums.php
└── views
│ └── .gitkeep
├── routes
└── web.php
├── storage
├── app
│ └── .gitignore
├── framework
│ ├── cache
│ │ ├── .gitignore
│ │ └── data
│ │ │ └── .gitignore
│ └── views
│ │ └── .gitignore
└── logs
│ └── .gitignore
└── tests
├── ExampleTest.php
├── Feature
└── ExampleTest.php
├── TestCase.php
├── Traits
└── CreatesApplication.php
└── Unit
└── ExampleTest.php
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 4
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
14 | [*.{yml,yaml}]
15 | indent_size = 2
16 |
--------------------------------------------------------------------------------
/.env.ci:
--------------------------------------------------------------------------------
1 | APP_NAME=lumen-api-starter
2 | APP_ENV=testing
3 | APP_KEY=kcTV8pvNMZUenldwhxRglPII85Xbkbwa
4 | APP_DEBUG=true
5 | APP_URL=http://lumen-api-starter.test
6 | APP_TIMEZONE=Asia/Shanghai
7 | APP_LOCALE=zh-CN
8 |
9 | DB_CONNECTION=sqlite
10 | DB_DATABASE=database/database.sqlite
11 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | APP_NAME=Lumen
2 | APP_ENV=local
3 | APP_KEY=
4 | APP_DEBUG=true
5 | APP_URL=http://localhost
6 | APP_TIMEZONE=UTC
7 |
8 | LOG_CHANNEL=stack
9 | LOG_SLACK_WEBHOOK_URL=
10 |
11 | DB_CONNECTION=mysql
12 | DB_HOST=127.0.0.1
13 | DB_PORT=3306
14 | DB_DATABASE=homestead
15 | DB_USERNAME=homestead
16 | DB_PASSWORD=secret
17 |
18 | CACHE_DRIVER=file
19 | QUEUE_CONNECTION=sync
20 |
21 | JWT_SECRET=
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "composer"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | tests:
8 | name: Tests
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - name: Checkout code
13 | uses: actions/checkout@v2
14 | - name: Setup PHP
15 | uses: shivammathur/setup-php@v2
16 | with:
17 | php-version: 8.1
18 | tools: pecl
19 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite,json,redis,mongodb
20 | coverage: none
21 | - name: Validate composer.json and composer.lock
22 | run: composer validate
23 | - name: Cache Composer packages
24 | id: composer-cache
25 | uses: actions/cache@v2
26 | with:
27 | path: vendor
28 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
29 | restore-keys: |
30 | ${{ runner.os }}-php-
31 | - name: Install dependencies
32 | if: steps.composer-cache.outputs.cache-hit != 'true'
33 | run: composer install --prefer-dist --no-progress --no-suggest --ignore-platform-reqs
34 | - name: Copy ENV Configuration for CI
35 | run: php -r "file_exists('.env') || copy('.env.ci', '.env');"
36 | - name: Create DB and schemas
37 | run: |
38 | mkdir -p database
39 | touch database/database.sqlite
40 | php artisan migrate
41 | - name: Execute tests (Unit and Feature tests) via PHPUnit
42 | run: vendor/bin/phpunit
43 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /.idea
3 | Homestead.json
4 | Homestead.yaml
5 | .env
6 | .phpunit.result.cache
7 | .php_cs.cache
8 |
--------------------------------------------------------------------------------
/.php_cs.dist:
--------------------------------------------------------------------------------
1 |
12 |
13 | This source file is subject to the MIT license that is bundled
14 | with this source code in the file LICENSE.
15 | EOF;
16 |
17 | $finder = PhpCsFixer\Finder::create()
18 | ->exclude('vendor')
19 | ->exclude('tests/Fixtures')
20 | ->in(__DIR__)
21 | ->append([__DIR__.'/php-cs-fixer']);
22 |
23 | $rules = [
24 | '@PSR2' => true,
25 | // PHPDoc should contain `@param` for all params.
26 | 'phpdoc_add_missing_param_annotation' => ['only_untyped'=>false],
27 | // Annotations in PHPDoc should be ordered so that `@param` annotations come first, then `@throws` annotations, then `@return` annotations.
28 | 'phpdoc_order' => false,
29 | // Annotations in PHPDoc should be grouped together so that annotations of the same type immediately follow each other, and annotations of a different type are separated by a single blank line.
30 | 'phpdoc_separation' => false,
31 | // There should not be a binary flag before strings.
32 | 'no_binary_string' => true,
33 | // Replace control structure alternative syntax to use braces.
34 | 'no_alternative_syntax' => true,
35 | // There should be no empty lines after class opening brace.
36 | 'no_blank_lines_after_class_opening' => true,
37 | // There should not be blank lines between docblock and the documented element.
38 | 'no_blank_lines_after_phpdoc' => true,
39 | // There must be a comment when fall-through is intentional in a non-empty case body.
40 | 'no_break_comment' => true,
41 | // The closing `? >` tag MUST be omitted from files containing only PHP.
42 | 'no_closing_tag' => true,
43 | // There should not be any empty comments.
44 | 'no_empty_comment' => true,
45 | // There should not be empty PHPDoc blocks.
46 | 'no_empty_phpdoc' => true,
47 | // Remove useless semicolon statements.
48 | 'no_empty_statement' => true,
49 | // Removes extra blank lines and/or blank lines following configuration.
50 | 'no_extra_blank_lines' => true,
51 | // Remove leading slashes in `use` clauses.
52 | 'no_leading_import_slash' => true,
53 | // The namespace declaration line shouldn't contain leading whitespace.
54 | 'no_leading_namespace_whitespace' => true,
55 | // Either language construct `print` or `echo` should be used.
56 | 'no_mixed_echo_print' => true,
57 | // Operator `=>` should not be surrounded by multi-line whitespaces.
58 | 'no_multiline_whitespace_around_double_arrow' => true,
59 | // Short cast `bool` using double exclamation mark should not be used.
60 | 'no_short_bool_cast' => true,
61 | // Replace short-echo `=` with long format ` true,
63 | // Single-line whitespace before closing semicolon are prohibited.
64 | 'no_singleline_whitespace_before_semicolons' => true,
65 | // When making a method or function call, there MUST NOT be a space between the method or function name and the opening parenthesis.
66 | 'no_spaces_after_function_name' => true,
67 | // There MUST NOT be spaces around offset braces.
68 | 'no_spaces_around_offset' => true,
69 | // There MUST NOT be a space after the opening parenthesis. There MUST NOT be a space before the closing parenthesis.
70 | 'no_spaces_inside_parenthesis' => true,
71 | // Replaces superfluous `elseif` with `if`.
72 | 'no_superfluous_elseif' => true,
73 | // PHP arrays should be declared using the configured syntax.ƒ
74 | 'array_syntax' => ['syntax'=>'short'],
75 | // Binary operators should be surrounded by space as configured.
76 | 'binary_operator_spaces' => true,
77 | // There MUST be one blank line after the namespace declaration.
78 | 'blank_line_after_namespace' => true,
79 | // Ensure there is no code on the same line as the PHP open tag and it is followed by a blank line.
80 | 'blank_line_after_opening_tag' => true,
81 | // An empty line feed must precede any configured statement.
82 | 'blank_line_before_statement' => true,
83 | // The body of each structure MUST be enclosed by braces. Braces should be properly placed. Body of braces should be properly indented.
84 | 'braces' => true,
85 | // A single space or none should be between cast and variable.
86 | 'cast_spaces' => true,
87 | // Class, trait and interface elements must be separated with one blank line.
88 | 'class_attributes_separation' => true,
89 | // Whitespace around the keywords of a class, trait or interfaces definition should be one space.
90 | 'class_definition' => true,
91 | // Concatenation should be spaced according configuration.
92 | 'concat_space' => true,
93 | // The PHP constants `true`, `false`, and `null` MUST be written using the correct casing.
94 | 'constant_case' => true,
95 | // Equal sign in declare statement should be surrounded by spaces or not following configuration.
96 | 'declare_equal_normalize' => ['space'=>'single'],
97 | // The keyword `elseif` should be used instead of `else if` so that all control keywords look like single words.
98 | 'elseif' => true,
99 | // PHP code MUST use only UTF-8 without BOM (remove BOM).
100 | 'encoding' => true,
101 | // Each line of multi-line DocComments must have an asterisk [PSR-5] and must be aligned with the first one.
102 | 'align_multiline_comment' => true,
103 | // Each element of an array must be indented exactly once.
104 | 'array_indentation' => true,
105 | // Using `isset($var) &&` multiple times should be done in one call.
106 | 'combine_consecutive_issets' => true,
107 | // Calling `unset` on multiple items should be done in one call.
108 | 'combine_consecutive_unsets' => true,
109 | // Remove extra spaces in a nullable typehint.
110 | 'compact_nullable_typehint' => true,
111 | // Escape implicit backslashes in strings and heredocs to ease the understanding of which are special chars interpreted by PHP and which not.
112 | 'escape_implicit_backslashes' => true,
113 | // Converts backtick operators to `shell_exec` calls.
114 | 'backtick_to_shell_exec' => true,
115 | // Orders the elements of classes/interfaces/traits.
116 | 'ordered_class_elements' => ['sortAlgorithm'=>'alpha'],
117 | 'header_comment' => ['header' => $header],
118 | ];
119 |
120 | $config = PhpCsFixer\Config::create()
121 | ->setRiskyAllowed(true)
122 | ->setRules($rules)
123 | ->setFinder($finder);
124 |
125 | return $config;
126 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | php:
2 | preset: laravel
3 | disabled:
4 | - unused_use
5 | js: true
6 | css: true
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Jiannei
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Lumen Api Starter Designed With ❤️
2 |
3 | 基于最新版本的 Lumen 基础构建的一个**基础功能**完备,**规范统一**,能够**快速**应用于实际的 API 项目开发启动模板。同时,也希望通过**合理的**架构设计使其适用于中大型项目。
4 |
5 | 少许的依赖安装,遵循 Laravel 的思维进行扩展,不额外增加「负担」。
6 |
7 | 开箱即用,加速 Api 开发。
8 |
9 | 
10 | 
11 |
12 | ### 社区讨论传送
13 |
14 | - [是时候使用 Lumen 8 + API Resource 开发项目了!](https://learnku.com/articles/45311)
15 | - [一篇 RESTful API 路由设计的最佳实践](https://learnku.com/articles/45526)
16 | - [教你更优雅地写 API 之「规范响应数据」](https://learnku.com/articles/52784)
17 | - [教你更优雅地写 API 之「枚举使用」](https://learnku.com/articles/53015)
18 | - [教你更优雅地写 API 之「记录日志」](https://learnku.com/articles/53669)
19 |
20 | ## 概览
21 |
22 | ### 说明
23 |
24 | 开始了解本项目前,引用一段[官方说明](https://lumen.laravel.com/docs/10.x/installation#installation)
25 |
26 | > 在发布Lumen后的几年里,PHP进行了各种出色的性能改进。因此,随着Laravel Octane的推出,我们不再建议您使用Lumen开始新项目。相反,我们建议始终使用Laravel开始新项目。
27 |
28 | 项目会继续更新维护,当中使用到 package 也会继续更新同时支持 laravel/lumen 新版本。API 规范没有严格意义上的标准,能适用于团队,让项目更好维护的规范就是好的规范,欢迎一起讨论。
29 |
30 | 项目laravel版本[传送地址](https://github.com/jiannei/laravel-api-starter)
31 |
32 | ### 支持情况
33 |
34 | - RESTful 规范的HTTP 响应结构:成功、失败、异常场景统一结构响应;多语言提示返回
35 | - 更为便捷地使用枚举/常量
36 | - Jwt-auth 方式授权
37 | - Repository & Service」架构设计参考
38 |
39 | ### 目录结构
40 |
41 | ```
42 | ├── app
43 | │ ├── Console
44 | │ │ ├── Commands // cli command:通常用于实现轮询任务
45 | │ │ └── Kernel.php // Schedule 调度
46 | │ ├── Contracts // 定义 interface
47 | │ ├── Enums // 定义枚举:要求php8.1以上版本,且laravel9.x以上版本 https://laravel.com/docs/9.x/releases#enum-casting
48 | │ │ └── ResponseCode.php
49 | │ ├── Events // 事件处理
50 | │ │ ├── Event.php
51 | │ │ └── ExampleEvent.php
52 | │ ├── Exceptions // 异常处理:结合 jiannei/laravel-response,可以更方便处理异常信息响应
53 | │ │ └── Handler.php
54 | │ ├── Http
55 | │ │ ├── Controllers // Controller 层根据 Request 将任务分发给不同 Service 处理,返回响应给客户端
56 | │ │ │ ├── AuthController.php // 包含 jwt 授权示例
57 | │ │ │ ├── Controller.php
58 | │ │ │ └── UsersController.php // 包含 laravel-response 使用示例
59 | │ │ ├── Middleware
60 | │ │ │ └── Authenticate.php // 统一401响应
61 | │ │ └── Resources
62 | │ │ └── UserResource.php // 使用 API 转换资源数据
63 | │ ├── Jobs // 异步任务
64 | │ │ ├── ExampleJob.php
65 | │ │ └── Job.php
66 | │ ├── Listeners // 监听事件处理
67 | │ │ └── ExampleListener.php
68 | │ ├── Models // Laravel 原始的 Eloquent\Model:定义数据表特性、数据表之间的关联关系等;不处理业务
69 | │ │ └── User.php
70 | │ ├── Providers // 各种服务容器
71 | │ │ ├── AppServiceProvider.php
72 | │ │ ├── AuthServiceProvider.php
73 | │ │ └── EventServiceProvider.php
74 | │ ├── Services // Service 层:处理实际业务;调用 Model 取资源数据,分发 Job、Eevent 等
75 | │ │ └── UserService.php
76 | │ └── Support // 对框架的扩展,或者实际项目中需要封装一些与业务无关的通用功能集
77 | │ ├── Traits
78 | │ │ ├── Helpers.php // Class 中常用的辅助功能集
79 | │ │ └── SerializeDate.php
80 | │ └── helpers.php // 全局会用到的辅助函数
81 | ```
82 |
83 | ## Repository & Service 模式架构
84 |
85 | ```
86 | Controller => 校验请求后调用不同 service 进行业务处理,调用 API Resource 转换资源数据返回
87 | Service => 具体的业务实现,调用 Model 取资源数据,处理业务,分发 event、job,
88 | Model => 维护资源数据的定义,以及数据之间的关联关系
89 | ```
90 |
91 | ### 实际案例
92 |
93 | 为了更好地理解 Repository & Service 模式,对 Laravel 中文社区的教程 2 中的 Larabbs 项目使用该模式进行了重构,实际开发过程可以参考其中的分层设计。
94 |
95 | [larabbs](https://github.com/Jiannei/larabbs)
96 |
97 | ### 职责说明
98 |
99 | **Controller 岗位职责**:
100 |
101 | 1. 校验是否有必要处理请求,是否有权限和是否请求参数合法等。无权限或不合法请求直接 response 返回格式统一的数据
102 | 2. 将校验后的参数或 Request 传入 Service 中具体的方法,安排 Service 实现具体的功能业务逻辑
103 | 3. Controller 中可以通过`__construct()`依赖注入多个 Service。比如 `UserController` 中可能会注入 `UserService`(用户相关的功能业务)和 `EmailService`(邮件相关的功能业务)
104 | 4. 使用统一的 `$this->response`调用`sucess`或`fail`方法来返回统一的数据格式
105 | 5. 使用 Laravel Api Resource 的同学可能在 Controller 中还会有转换数据的逻辑。比如,`return Response::success(new UserCollection($resource));`或`return Response::success(new UserResource($user));`
106 |
107 | **Service 岗位职责**:
108 |
109 | 1. 实现项目中的具体**功能**业务。所以 Service 中定义的方法名,应该是用来**描述功能或业务**的(动词+业务描述)。比如`handleListPageDisplay`和`handleProfilePageDisplay`,分别对应用户列表展示和用户详情页展示的需求。
110 | 2. 处理 Controller 中传入的参数,进行**业务判断**
111 | 3.(可选)根据业务需求配置相应的 Criteria 和 Presenter 后(不需要的可以不用配置,或者将通用的配置到 Repository 中)
112 | 4. 调用 Repository 处理**数据的逻辑**
113 | 5. Service 可以不注入 Repository,或者只注入与处理当前业务**存在数据关联**的 Repository。比如,`EmailService`中或许就只有调用第三方 API 的逻辑,不需要更新维护系统中的数据,就不需要注入 Repository;`OrderService`中实现了订单出库逻辑后,还需要生成相应的财务结算单据,就需要注入 `OrderReposoitory`和`FinancialDocumentRepository`,财务单据中的原单号关联着订单号,存在着数据关联。
114 | 6. Service 中不允许调用其他 Service,保持职责单一,如有需要,应该考虑 Controller 中调用
115 |
116 | **Model 岗位职责**:
117 |
118 | Model 层只需要相对简单地数据定义就可以了。比如,对数据表的定义,字段的映射,以及数据表之间关联关系等。
119 |
120 | ### 规范
121 |
122 | * 命名规范:
123 |
124 | - controller:
125 | - 类名:名词,复数形式,描述是对整个资源集合进行操作;当没有集合概念的时候。换句话说,当资源只有一个的情况下,使用单数资源名称也是可以的——即一个单一的资源。例如,如果有一个单一的总体配置资源,你可以使用一个单数名称来表示
126 | - 方法名:动词+名词,体现资源操作。如,store\destroy
127 |
128 | - service:
129 | - 类名:名词,单数。比如`UserService`、`EmailService`和`OrderService`
130 | - 方法名:`动词+名词`,描述能够实现的业务需求。比如:`handleRegistration`表示实现用户注册功能。
131 |
132 | * 使用规范:待补充
133 |
134 | ## Packages
135 |
136 | - [jiannei/laravel-response](https://github.com/jiannei/laravel-response):规范统一的响应数据格式
137 | - [jiannei/laravel-response](https://github.com/jiannei/laravel-enum):多语言的枚举支持
138 | - [tymon/jwt-auth](https://github.com/tymondesigns/jwt-auth):默认支持 JWT 授权
139 |
140 | ## 参考
141 |
142 | * [RESTful API 最佳实践](https://learnku.com/articles/13797/restful-api-best-practice)
143 | * [RESTful 服务最佳实践](https://www.cnblogs.com/jaxu/p/7908111.html)
144 |
145 | ## License
146 |
147 | The Lumen Api Starter is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
148 |
--------------------------------------------------------------------------------
/app/Console/Commands/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiannei/lumen-api-starter/75deefb2e256fb334674f0e1717b27084f32bd49/app/Console/Commands/.gitkeep
--------------------------------------------------------------------------------
/app/Console/Kernel.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Console;
13 |
14 | use Illuminate\Console\Scheduling\Schedule;
15 | use Laravel\Lumen\Console\Kernel as ConsoleKernel;
16 |
17 | class Kernel extends ConsoleKernel
18 | {
19 | /**
20 | * The Artisan commands provided by your application.
21 | *
22 | * @var array
23 | */
24 | protected $commands = [
25 | ];
26 |
27 | /**
28 | * Define the application's command schedule.
29 | *
30 | * @return void
31 | */
32 | protected function schedule(Schedule $schedule)
33 | {
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/Enums/ResponseCode.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Enums;
13 |
14 | use Jiannei\Enum\Laravel\Support\Traits\EnumEnhance;
15 |
16 | enum ResponseCode: int
17 | {
18 | use EnumEnhance;
19 |
20 | case SERVICE_REGISTER_SUCCESS = 200101;
21 | case SERVICE_LOGIN_SUCCESS = 200102;
22 |
23 | // 业务操作错误码(外部服务或内部服务调用...)
24 | case SERVICE_REGISTER_ERROR = 500101;
25 | case SERVICE_LOGIN_ERROR = 500102;
26 |
27 | // 客户端错误码:400 ~ 499 开头,后拼接 3 位
28 | case CLIENT_PARAMETER_ERROR = 400001;
29 | case CLIENT_CREATED_ERROR = 400002;
30 | case CLIENT_DELETED_ERROR = 400003;
31 |
32 | // 服务端操作错误码:500 ~ 599 开头,后拼接 3 位
33 | case SYSTEM_ERROR = 500001;
34 | case SYSTEM_UNAVAILABLE = 500002;
35 | case SYSTEM_CACHE_CONFIG_ERROR = 500003;
36 | case SYSTEM_CACHE_MISSED_ERROR = 500004;
37 | case SYSTEM_CONFIG_ERROR = 500005;
38 | }
39 |
--------------------------------------------------------------------------------
/app/Events/Event.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Events;
13 |
14 | use Illuminate\Queue\SerializesModels;
15 |
16 | abstract class Event
17 | {
18 | use SerializesModels;
19 | }
20 |
--------------------------------------------------------------------------------
/app/Events/ExampleEvent.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Events;
13 |
14 | class ExampleEvent extends Event
15 | {
16 | /**
17 | * Create a new event instance.
18 | *
19 | * @return void
20 | */
21 | public function __construct()
22 | {
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/Exceptions/Handler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Exceptions;
13 |
14 | use Illuminate\Auth\Access\AuthorizationException;
15 | use Illuminate\Database\Eloquent\ModelNotFoundException;
16 | use Illuminate\Validation\ValidationException;
17 | use Jiannei\Response\Laravel\Support\Traits\ExceptionTrait;
18 | use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
19 | use Symfony\Component\HttpKernel\Exception\HttpException;
20 | use Throwable;
21 |
22 | class Handler extends ExceptionHandler
23 | {
24 | use ExceptionTrait;
25 |
26 | /**
27 | * A list of the exception types that should not be reported.
28 | *
29 | * @var array
30 | */
31 | protected $dontReport = [
32 | AuthorizationException::class,
33 | HttpException::class,
34 | ModelNotFoundException::class,
35 | ValidationException::class,
36 | ];
37 |
38 | /**
39 | * Report or log an exception.
40 | *
41 | * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
42 | *
43 | * @return void
44 | *
45 | * @throws \Exception
46 | */
47 | public function report(Throwable $exception)
48 | {
49 | parent::report($exception);
50 | }
51 |
52 | /**
53 | * Render an exception into an HTTP response.
54 | *
55 | * @param \Illuminate\Http\Request $request
56 | *
57 | * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
58 | *
59 | * @throws \Throwable
60 | */
61 | public function render($request, Throwable $exception)
62 | {
63 | return parent::render($request, $exception);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/Http/Controllers/AuthController.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Http\Controllers;
13 |
14 | use Jiannei\Response\Laravel\Support\Facades\Response;
15 |
16 | class AuthController extends Controller
17 | {
18 | /**
19 | * Create a new AuthController instance.
20 | *
21 | * @return void
22 | */
23 | public function __construct()
24 | {
25 | $this->middleware('auth:api', ['except' => ['login']]);
26 | }
27 |
28 | /**
29 | * Get a JWT via given credentials.
30 | *
31 | * @return \Illuminate\Http\JsonResponse
32 | */
33 | public function login()
34 | {
35 | $credentials = request(['email', 'password']);
36 |
37 | if (!$token = auth()->attempt($credentials)) {
38 | return Response::errorUnauthorized();
39 | }
40 |
41 | return $this->respondWithToken($token);
42 | }
43 |
44 | /**
45 | * Get the authenticated User.
46 | *
47 | * @return \Illuminate\Http\JsonResponse
48 | */
49 | public function me()
50 | {
51 | return Response::success(auth()->user());
52 | }
53 |
54 | /**
55 | * Log the user out (Invalidate the token).
56 | *
57 | * @return \Illuminate\Http\JsonResponse
58 | */
59 | public function logout()
60 | {
61 | auth()->logout();
62 |
63 | return Response::ok('Successfully logged out');
64 | }
65 |
66 | /**
67 | * Refresh a token.
68 | *
69 | * @return \Illuminate\Http\JsonResponse
70 | */
71 | public function refresh()
72 | {
73 | return $this->respondWithToken(auth()->refresh());
74 | }
75 |
76 | /**
77 | * Get the token array structure.
78 | *
79 | * @param string $token
80 | *
81 | * @return \Illuminate\Http\JsonResponse
82 | */
83 | protected function respondWithToken($token)
84 | {
85 | return Response::success([
86 | 'access_token' => $token,
87 | 'token_type' => 'bearer',
88 | 'expires_in' => auth()->factory()->getTTL() * 60,
89 | ]);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Http\Controllers;
13 |
14 | use Laravel\Lumen\Routing\Controller as BaseController;
15 |
16 | abstract class Controller extends BaseController
17 | {
18 | }
19 |
--------------------------------------------------------------------------------
/app/Http/Controllers/UsersController.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Http\Controllers;
13 |
14 | use App\Http\Resources\UserResource;
15 | use App\Services\UserService;
16 | use Illuminate\Http\Request;
17 | use Jiannei\Response\Laravel\Support\Facades\Response;
18 |
19 | class UsersController extends Controller
20 | {
21 | public function __construct(private UserService $service)
22 | {
23 | $this->middleware('auth:api', ['except' => ['store', 'show']]);
24 | }
25 |
26 | public function index(string $paginate = 'paginate')
27 | {
28 | $users = match ($paginate) {
29 | 'simple' => $this->service->handleSearchSimpleList(),
30 | 'cursor' => $this->service->handleSearchCursorList(),
31 | default => $this->service->handleSearchList(),
32 | };
33 |
34 | return Response::success(UserResource::collection($users));
35 | }
36 |
37 | public function show($id)
38 | {
39 | $user = $this->service->handleSearchItem($id);
40 |
41 | return Response::success($user);
42 | }
43 |
44 | public function store(Request $request)
45 | {
46 | $this->validate($request, [
47 | 'name' => 'required|string|max:100',
48 | 'email' => 'required|email|unique:users,email',
49 | 'password' => 'required|min:8',
50 | ]);
51 |
52 | $user = $this->service->handleCreateItem($request->all());
53 |
54 | return Response::created(new UserResource($user));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/Http/Middleware/Authenticate.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Http\Middleware;
13 |
14 | use Closure;
15 | use Illuminate\Contracts\Auth\Factory as Auth;
16 | use Jiannei\Response\Laravel\Support\Facades\Response;
17 |
18 | class Authenticate
19 | {
20 | /**
21 | * The authentication guard factory instance.
22 | *
23 | * @var \Illuminate\Contracts\Auth\Factory
24 | */
25 | protected $auth;
26 |
27 | /**
28 | * Create a new middleware instance.
29 | *
30 | * @return void
31 | */
32 | public function __construct(Auth $auth)
33 | {
34 | $this->auth = $auth;
35 | }
36 |
37 | /**
38 | * Handle an incoming request.
39 | *
40 | * @param \Illuminate\Http\Request $request
41 | * @param string|null $guard
42 | *
43 | * @return mixed
44 | */
45 | public function handle($request, Closure $next, $guard = null)
46 | {
47 | if ($this->auth->guard($guard)->guest()) {
48 | return Response::errorUnauthorized();
49 | }
50 |
51 | return $next($request);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/Http/Resources/UserResource.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Http\Resources;
13 |
14 | use Illuminate\Http\Resources\Json\JsonResource;
15 |
16 | class UserResource extends JsonResource
17 | {
18 | public function toArray($request)
19 | {
20 | return [
21 | 'nickname' => $this->name,
22 | 'email' => $this->email,
23 | ];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/Jobs/ExampleJob.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Jobs;
13 |
14 | class ExampleJob extends Job
15 | {
16 | /**
17 | * Create a new job instance.
18 | *
19 | * @return void
20 | */
21 | public function __construct()
22 | {
23 | }
24 |
25 | /**
26 | * Execute the job.
27 | *
28 | * @return void
29 | */
30 | public function handle()
31 | {
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/Jobs/Job.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Jobs;
13 |
14 | use Illuminate\Bus\Queueable;
15 | use Illuminate\Contracts\Queue\ShouldQueue;
16 | use Illuminate\Queue\InteractsWithQueue;
17 | use Illuminate\Queue\SerializesModels;
18 |
19 | abstract class Job implements ShouldQueue
20 | {
21 | /*
22 | |--------------------------------------------------------------------------
23 | | Queueable Jobs
24 | |--------------------------------------------------------------------------
25 | |
26 | | This job base class provides a central location to place any logic that
27 | | is shared across all of your jobs. The trait included with the class
28 | | provides access to the "queueOn" and "delay" queue helper methods.
29 | |
30 | */
31 |
32 | use InteractsWithQueue;
33 | use Queueable;
34 | use SerializesModels;
35 | }
36 |
--------------------------------------------------------------------------------
/app/Listeners/ExampleListener.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Listeners;
13 |
14 | use App\Events\ExampleEvent;
15 |
16 | class ExampleListener
17 | {
18 | /**
19 | * Create the event listener.
20 | *
21 | * @return void
22 | */
23 | public function __construct()
24 | {
25 | }
26 |
27 | /**
28 | * Handle the event.
29 | *
30 | * @return void
31 | */
32 | public function handle(ExampleEvent $event)
33 | {
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/Models/User.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Models;
13 |
14 | use Illuminate\Auth\Authenticatable;
15 | use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
16 | use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
17 | use Illuminate\Database\Eloquent\Factories\HasFactory;
18 | use Illuminate\Database\Eloquent\Model;
19 | use Laravel\Lumen\Auth\Authorizable;
20 | use Tymon\JWTAuth\Contracts\JWTSubject;
21 |
22 | class User extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
23 | {
24 | use Authenticatable;
25 | use Authorizable;
26 | use HasFactory;
27 |
28 | /**
29 | * The attributes that are mass assignable.
30 | *
31 | * @var string[]
32 | */
33 | protected $fillable = [
34 | 'name', 'email',
35 | ];
36 |
37 | /**
38 | * The attributes excluded from the model's JSON form.
39 | *
40 | * @var string[]
41 | */
42 | protected $hidden = [
43 | 'password',
44 | ];
45 |
46 | /**
47 | * Get the identifier that will be stored in the subject claim of the JWT.
48 | *
49 | * @return mixed
50 | */
51 | public function getJWTIdentifier()
52 | {
53 | return $this->getKey();
54 | }
55 |
56 | /**
57 | * Return a key value array, containing any custom claims to be added to the JWT.
58 | *
59 | * @return array
60 | */
61 | public function getJWTCustomClaims()
62 | {
63 | return [];
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/Providers/AppServiceProvider.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Providers;
13 |
14 | use Illuminate\Support\ServiceProvider;
15 |
16 | class AppServiceProvider extends ServiceProvider
17 | {
18 | /**
19 | * Register any application services.
20 | *
21 | * @return void
22 | */
23 | public function register()
24 | {
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/Providers/AuthServiceProvider.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Providers;
13 |
14 | use App\Models\User;
15 | use Illuminate\Support\ServiceProvider;
16 |
17 | class AuthServiceProvider extends ServiceProvider
18 | {
19 | /**
20 | * Register any application services.
21 | *
22 | * @return void
23 | */
24 | public function register()
25 | {
26 | }
27 |
28 | /**
29 | * Boot the authentication services for the application.
30 | *
31 | * @return void
32 | */
33 | public function boot()
34 | {
35 | // Here you may define how you wish users to be authenticated for your Lumen
36 | // application. The callback which receives the incoming request instance
37 | // should return either a User instance or null. You're free to obtain
38 | // the User instance via an API token or any other method necessary.
39 |
40 | $this->app['auth']->viaRequest('api', function ($request) {
41 | if ($request->input('api_token')) {
42 | return User::where('api_token', $request->input('api_token'))->first();
43 | }
44 | });
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/Providers/EventServiceProvider.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Providers;
13 |
14 | use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;
15 |
16 | class EventServiceProvider extends ServiceProvider
17 | {
18 | /**
19 | * The event listener mappings for the application.
20 | *
21 | * @var array
22 | */
23 | protected $listen = [
24 | \App\Events\ExampleEvent::class => [
25 | \App\Listeners\ExampleListener::class,
26 | ],
27 | ];
28 |
29 | /**
30 | * Determine if events and listeners should be automatically discovered.
31 | *
32 | * @return bool
33 | */
34 | public function shouldDiscoverEvents()
35 | {
36 | return false;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/Services/UserService.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Services;
13 |
14 | use App\Models\User;
15 |
16 | class UserService
17 | {
18 | public function handleSearchList()
19 | {
20 | return User::query()->paginate();
21 | }
22 |
23 | public function handleSearchSimpleList()
24 | {
25 | return User::query()->simplePaginate();
26 | }
27 |
28 | public function handleSearchCursorList()
29 | {
30 | return User::query()->cursorPaginate();
31 | }
32 |
33 | public function handleSearchItem($id)
34 | {
35 | return User::query()->findOrFail($id);
36 | }
37 |
38 | public function handleCreateItem(array $data)
39 | {
40 | return User::query()->create($data);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/Support/Traits/Helpers.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Support\Traits;
13 |
14 | trait Helpers
15 | {
16 | }
17 |
--------------------------------------------------------------------------------
/app/Support/Traits/SerializeDate.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace App\Support\Traits;
13 |
14 | use Carbon\Carbon;
15 | use DateTimeInterface;
16 |
17 | trait SerializeDate
18 | {
19 | /**
20 | * 为数组 / JSON 序列化准备日期。(Laravel 7).
21 | *
22 | * @return string
23 | */
24 | protected function serializeDate(DateTimeInterface $date)
25 | {
26 | return $date->format($this->dateFormat ?: Carbon::DEFAULT_TO_STRING_FORMAT);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/Support/helpers.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
--------------------------------------------------------------------------------
/artisan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | make(
32 | 'Illuminate\Contracts\Console\Kernel'
33 | );
34 |
35 | exit($kernel->handle(new ArgvInput, new ConsoleOutput));
36 |
--------------------------------------------------------------------------------
/bootstrap/app.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | require_once __DIR__.'/../vendor/autoload.php';
13 |
14 | (new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
15 | dirname(__DIR__)
16 | ))->bootstrap();
17 |
18 | date_default_timezone_set(env('APP_TIMEZONE', 'UTC'));
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Create The Application
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here we will load the environment and create the application instance
26 | | that serves as the central piece of this framework. We'll use this
27 | | application as an "IoC" container and router for this framework.
28 | |
29 | */
30 |
31 | $app = new Laravel\Lumen\Application(
32 | dirname(__DIR__)
33 | );
34 |
35 | $app->withFacades();
36 |
37 | $app->withEloquent();
38 |
39 | /*
40 | |--------------------------------------------------------------------------
41 | | Register Container Bindings
42 | |--------------------------------------------------------------------------
43 | |
44 | | Now we will register a few bindings in the service container. We will
45 | | register the exception handler and the console kernel. You may add
46 | | your own bindings here if you like or you can make another file.
47 | |
48 | */
49 |
50 | $app->singleton(
51 | Illuminate\Contracts\Debug\ExceptionHandler::class,
52 | App\Exceptions\Handler::class
53 | );
54 |
55 | $app->singleton(
56 | Illuminate\Contracts\Console\Kernel::class,
57 | App\Console\Kernel::class
58 | );
59 |
60 | /*
61 | |--------------------------------------------------------------------------
62 | | Register Config Files
63 | |--------------------------------------------------------------------------
64 | |
65 | | Now we will register the "app" configuration file. If the file exists in
66 | | your configuration directory it will be loaded; otherwise, we'll load
67 | | the default version. You may register other files below as needed.
68 | |
69 | */
70 |
71 | $app->configure('app');
72 | $app->configure('response');
73 | $app->configure('jwt');
74 |
75 | /*
76 | |--------------------------------------------------------------------------
77 | | Register Middleware
78 | |--------------------------------------------------------------------------
79 | |
80 | | Next, we will register the middleware with the application. These can
81 | | be global middleware that run before and after each request into a
82 | | route or middleware that'll be assigned to some specific routes.
83 | |
84 | */
85 |
86 | // $app->middleware([
87 | // App\Http\Middleware\ExampleMiddleware::class
88 | // ]);
89 |
90 | $app->routeMiddleware([
91 | 'auth' => App\Http\Middleware\Authenticate::class,
92 | ]);
93 |
94 | /*
95 | |--------------------------------------------------------------------------
96 | | Register Service Providers
97 | |--------------------------------------------------------------------------
98 | |
99 | | Here we will register all of the application's service providers which
100 | | are used to bind services into the container. Service providers are
101 | | totally optional, so you are not required to uncomment this line.
102 | |
103 | */
104 |
105 | // $app->register(App\Providers\AppServiceProvider::class);
106 | $app->register(App\Providers\AuthServiceProvider::class);
107 | // $app->register(App\Providers\EventServiceProvider::class);
108 | $app->register(\Jiannei\Response\Laravel\Providers\LumenServiceProvider::class);
109 | $app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);
110 |
111 | /*
112 | |--------------------------------------------------------------------------
113 | | Load The Application Routes
114 | |--------------------------------------------------------------------------
115 | |
116 | | Next we will include the routes file so that they can all be added to
117 | | the application. This will provide all of the URLs the application
118 | | can respond to, as well as the controllers that may handle them.
119 | |
120 | */
121 |
122 | $app->router->group([
123 | 'namespace' => 'App\Http\Controllers',
124 | ], function ($router) {
125 | require __DIR__.'/../routes/web.php';
126 | });
127 |
128 | return $app;
129 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "laravel/lumen",
3 | "description": "The Laravel Lumen Framework.",
4 | "keywords": ["framework", "laravel", "lumen"],
5 | "license": "MIT",
6 | "type": "project",
7 | "require": {
8 | "php": "^8.1",
9 | "jiannei/laravel-enum": "dev-main",
10 | "jiannei/laravel-response": "dev-main",
11 | "laravel/lumen-framework": "^10.0",
12 | "tymon/jwt-auth": "^2.0"
13 | },
14 | "require-dev": {
15 | "fakerphp/faker": "^1.9.1",
16 | "mockery/mockery": "^1.4.4",
17 | "phpunit/phpunit": "^10.0"
18 | },
19 | "autoload": {
20 | "files": [
21 | "app/Support/helpers.php"
22 | ],
23 | "psr-4": {
24 | "App\\": "app/",
25 | "Database\\Factories\\": "database/factories/",
26 | "Database\\Seeders\\": "database/seeders/"
27 | }
28 | },
29 | "autoload-dev": {
30 | "psr-4": {
31 | "Tests\\": "tests/"
32 | }
33 | },
34 | "scripts": {
35 | "post-root-package-install": [
36 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
37 | ]
38 | },
39 | "config": {
40 | "optimize-autoloader": true,
41 | "preferred-install": "dist",
42 | "sort-packages": true
43 | },
44 | "minimum-stability": "stable",
45 | "prefer-stable": true
46 | }
47 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | return [
13 | /*
14 | |--------------------------------------------------------------------------
15 | | Application Name
16 | |--------------------------------------------------------------------------
17 | |
18 | | This value is the name of your application. This value is used when the
19 | | framework needs to place the application's name in a notification or
20 | | any other location as required by the application or its packages.
21 | |
22 | */
23 |
24 | 'name' => env('APP_NAME', 'Lumen'),
25 |
26 | /*
27 | |--------------------------------------------------------------------------
28 | | Application Environment
29 | |--------------------------------------------------------------------------
30 | |
31 | | This value determines the "environment" your application is currently
32 | | running in. This may determine how you prefer to configure various
33 | | services the application utilizes. Set this in your ".env" file.
34 | |
35 | */
36 |
37 | 'env' => env('APP_ENV', 'production'),
38 |
39 | /*
40 | |--------------------------------------------------------------------------
41 | | Application Debug Mode
42 | |--------------------------------------------------------------------------
43 | |
44 | | When your application is in debug mode, detailed error messages with
45 | | stack traces will be shown on every error that occurs within your
46 | | application. If disabled, a simple generic error page is shown.
47 | |
48 | */
49 |
50 | 'debug' => (bool) env('APP_DEBUG', false),
51 |
52 | /*
53 | |--------------------------------------------------------------------------
54 | | Application URL
55 | |--------------------------------------------------------------------------
56 | |
57 | | This URL is used by the console to properly generate URLs when using
58 | | the Artisan command line tool. You should set this to the root of
59 | | your application so that it is used when running Artisan tasks.
60 | |
61 | */
62 |
63 | 'url' => env('APP_URL', 'http://localhost'),
64 |
65 | /*
66 | |--------------------------------------------------------------------------
67 | | Application Timezone
68 | |--------------------------------------------------------------------------
69 | |
70 | | Here you may specify the default timezone for your application, which
71 | | will be used by the PHP date and date-time functions. We have gone
72 | | ahead and set this to a sensible default for you out of the box.
73 | |
74 | */
75 |
76 | 'timezone' => 'UTC',
77 |
78 | /*
79 | |--------------------------------------------------------------------------
80 | | Application Locale Configuration
81 | |--------------------------------------------------------------------------
82 | |
83 | | The application locale determines the default locale that will be used
84 | | by the translation service provider. You are free to set this value
85 | | to any of the locales which will be supported by the application.
86 | |
87 | */
88 |
89 | 'locale' => env('APP_LOCALE', 'en'),
90 |
91 | /*
92 | |--------------------------------------------------------------------------
93 | | Application Fallback Locale
94 | |--------------------------------------------------------------------------
95 | |
96 | | The fallback locale determines the locale to use when the current one
97 | | is not available. You may change the value to correspond to any of
98 | | the language folders that are provided through your application.
99 | |
100 | */
101 |
102 | 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),
103 |
104 | /*
105 | |--------------------------------------------------------------------------
106 | | Encryption Key
107 | |--------------------------------------------------------------------------
108 | |
109 | | This key is used by the Illuminate encrypter service and should be set
110 | | to a random, 32 character string, otherwise these encrypted strings
111 | | will not be safe. Please do this before deploying an application!
112 | |
113 | */
114 |
115 | 'key' => env('APP_KEY'),
116 |
117 | 'cipher' => 'AES-256-CBC',
118 | ];
119 |
--------------------------------------------------------------------------------
/config/auth.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | return [
13 | /*
14 | |--------------------------------------------------------------------------
15 | | Authentication Defaults
16 | |--------------------------------------------------------------------------
17 | |
18 | | This option controls the default authentication "guard" and password
19 | | reset options for your application. You may change these defaults
20 | | as required, but they're a perfect start for most applications.
21 | |
22 | */
23 |
24 | 'defaults' => [
25 | 'guard' => env('AUTH_GUARD', 'api'),
26 | ],
27 |
28 | /*
29 | |--------------------------------------------------------------------------
30 | | Authentication Guards
31 | |--------------------------------------------------------------------------
32 | |
33 | | Next, you may define every authentication guard for your application.
34 | | Of course, a great default configuration has been defined for you
35 | | here which uses session storage and the Eloquent user provider.
36 | |
37 | | All authentication drivers have a user provider. This defines how the
38 | | users are actually retrieved out of your database or other storage
39 | | mechanisms used by this application to persist your user's data.
40 | |
41 | | Supported: "token"
42 | |
43 | */
44 |
45 | 'guards' => [
46 | 'api' => [
47 | 'driver' => 'jwt',
48 | 'provider' => 'users',
49 | ],
50 | ],
51 |
52 | /*
53 | |--------------------------------------------------------------------------
54 | | User Providers
55 | |--------------------------------------------------------------------------
56 | |
57 | | All authentication drivers have a user provider. This defines how the
58 | | users are actually retrieved out of your database or other storage
59 | | mechanisms used by this application to persist your user's data.
60 | |
61 | | If you have multiple user tables or models you may configure multiple
62 | | sources which represent each model / table. These sources may then
63 | | be assigned to any extra authentication guards you have defined.
64 | |
65 | | Supported: "database", "eloquent"
66 | |
67 | */
68 |
69 | 'providers' => [
70 | 'users' => [
71 | 'driver' => 'eloquent',
72 | 'model' => \App\Models\User::class,
73 | ],
74 | ],
75 |
76 | /*
77 | |--------------------------------------------------------------------------
78 | | Resetting Passwords
79 | |--------------------------------------------------------------------------
80 | |
81 | | Here you may set the options for resetting passwords including the view
82 | | that is your password reset e-mail. You may also set the name of the
83 | | table that maintains all of the reset tokens for your application.
84 | |
85 | | You may specify multiple password reset configurations if you have more
86 | | than one user table or model in the application and you want to have
87 | | separate password reset settings based on the specific user types.
88 | |
89 | | The expire time is the number of minutes that the reset token should be
90 | | considered valid. This security feature keeps tokens short-lived so
91 | | they have less time to be guessed. You may change this as needed.
92 | |
93 | */
94 |
95 | 'passwords' => [
96 | ],
97 | ];
98 |
--------------------------------------------------------------------------------
/config/response.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | return [
13 | /*
14 | |--------------------------------------------------------------------------
15 | | Set the http status code when the response fails
16 | |--------------------------------------------------------------------------
17 | |
18 | | the reference options are false, 200, 500
19 | |
20 | | false, stricter http status codes such as 404, 401, 403, 500, etc. will be returned
21 | | 200, All failed responses will also return a 200 status code
22 | | 500, All failed responses return a 500 status code
23 | */
24 |
25 | 'error_code' => false,
26 |
27 | // lang/zh_CN/enums.php
28 | 'locale' => 'enums.'.\App\Enums\ResponseCode::class, // enums.\Jiannei\Enum\Laravel\Support\Enums\HttpStatusCode::class
29 |
30 | // You can set some attributes (eg:code/message/header/options) for the exception, and it will override the default attributes of the exception
31 | 'exception' => [
32 | \Illuminate\Validation\ValidationException::class => [
33 | 'code' => 422,
34 | ],
35 | \Illuminate\Auth\AuthenticationException::class => [
36 | ],
37 | \Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class => [
38 | 'message' => '',
39 | ],
40 | \Illuminate\Database\Eloquent\ModelNotFoundException::class => [
41 | 'message' => '',
42 | ],
43 | ],
44 |
45 | // Any key that returns data exists supports custom aliases and display.
46 | 'format' => [
47 | 'class' => \Jiannei\Response\Laravel\Support\Format::class,
48 | 'config' => [
49 | // key => config
50 | 'status' => ['alias' => 'status', 'show' => true],
51 | 'code' => ['alias' => 'code', 'show' => true],
52 | 'message' => ['alias' => 'message', 'show' => true],
53 | 'error' => ['alias' => 'error', 'show' => true],
54 | 'data' => ['alias' => 'data', 'show' => true],
55 | 'data.data' => ['alias' => 'data.data', 'show' => true], // rows/items/list
56 | ],
57 | ],
58 | ];
59 |
--------------------------------------------------------------------------------
/database/database.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiannei/lumen-api-starter/75deefb2e256fb334674f0e1717b27084f32bd49/database/database.sqlite
--------------------------------------------------------------------------------
/database/factories/PostFactory.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Database\Factories;
13 |
14 | use App\Repositories\Models\Post;
15 | use Illuminate\Database\Eloquent\Factories\Factory;
16 |
17 | class PostFactory extends Factory
18 | {
19 | protected $model = Post::class;
20 |
21 | public function definition()
22 | {
23 | return [
24 | 'title' => $this->faker->sentence,
25 | 'body' => $this->faker->paragraph(3),
26 | 'published' => $this->faker->numberBetween(0, 1),
27 | 'user_id' => $this->faker->randomElement([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/factories/UserFactory.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Database\Factories;
13 |
14 | use App\Models\User;
15 | use Illuminate\Database\Eloquent\Factories\Factory;
16 | use Illuminate\Support\Facades\Hash;
17 |
18 | class UserFactory extends Factory
19 | {
20 | /**
21 | * The name of the factory's corresponding model.
22 | *
23 | * @var string
24 | */
25 | protected $model = User::class;
26 |
27 | /**
28 | * Define the model's default state.
29 | *
30 | * @return array
31 | */
32 | public function definition()
33 | {
34 | return [
35 | 'name' => $this->faker->name,
36 | 'email' => $this->faker->unique()->safeEmail,
37 | 'password' => Hash::make('password'),
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/database/migrations/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiannei/lumen-api-starter/75deefb2e256fb334674f0e1717b27084f32bd49/database/migrations/.gitkeep
--------------------------------------------------------------------------------
/database/migrations/2020_05_30_115810_create_users_table.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | use Illuminate\Database\Migrations\Migration;
13 | use Illuminate\Database\Schema\Blueprint;
14 | use Illuminate\Support\Facades\Schema;
15 |
16 | class CreateUsersTable extends Migration
17 | {
18 | /**
19 | * Run the migrations.
20 | */
21 | public function up()
22 | {
23 | Schema::create('users', function (Blueprint $table) {
24 | $table->id();
25 | $table->string('name');
26 | $table->string('email')->unique();
27 | $table->string('password');
28 | $table->timestamps();
29 | });
30 | }
31 |
32 | /**
33 | * Reverse the migrations.
34 | */
35 | public function down()
36 | {
37 | Schema::dropIfExists('users');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/database/migrations/2020_10_16_105234_create_posts_table.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | use Illuminate\Database\Migrations\Migration;
13 | use Illuminate\Database\Schema\Blueprint;
14 | use Illuminate\Support\Facades\Schema;
15 |
16 | /**
17 | * Class CreatePostsTable.
18 | */
19 | class CreatePostsTable extends Migration
20 | {
21 | /**
22 | * Run the migrations.
23 | *
24 | * @return void
25 | */
26 | public function up()
27 | {
28 | Schema::create('posts', function (Blueprint $table) {
29 | $table->bigIncrements('id');
30 | $table->unsignedBigInteger('user_id');
31 | $table->text('title');
32 | $table->text('body');
33 | $table->boolean('published');
34 | $table->timestamps();
35 | });
36 | }
37 |
38 | /**
39 | * Reverse the migrations.
40 | *
41 | * @return void
42 | */
43 | public function down()
44 | {
45 | Schema::drop('posts');
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/database/seeders/DatabaseSeeder.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Database\Seeders;
13 |
14 | use Illuminate\Database\Seeder;
15 |
16 | class DatabaseSeeder extends Seeder
17 | {
18 | /**
19 | * Run the database seeds.
20 | *
21 | * @return void
22 | */
23 | public function run()
24 | {
25 | $this->call([
26 | UsersSeeder::class,
27 | ]);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/database/seeders/UsersSeeder.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Database\Seeders;
13 |
14 | use Database\Factories\UserFactory;
15 | use Illuminate\Database\Seeder;
16 |
17 | class UsersSeeder extends Seeder
18 | {
19 | public function run()
20 | {
21 | UserFactory::new()->count(30)->create();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | ./tests
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 |
3 | Options -MultiViews -Indexes
4 |
5 |
6 | RewriteEngine On
7 |
8 | # Handle Authorization Header
9 | RewriteCond %{HTTP:Authorization} .
10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
11 |
12 | # Redirect Trailing Slashes If Not A Folder...
13 | RewriteCond %{REQUEST_FILENAME} !-d
14 | RewriteCond %{REQUEST_URI} (.+)/$
15 | RewriteRule ^ %1 [L,R=301]
16 |
17 | # Handle Front Controller...
18 | RewriteCond %{REQUEST_FILENAME} !-d
19 | RewriteCond %{REQUEST_FILENAME} !-f
20 | RewriteRule ^ index.php [L]
21 |
22 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | $app = require __DIR__.'/../bootstrap/app.php';
13 |
14 | /*
15 | |--------------------------------------------------------------------------
16 | | Run The Application
17 | |--------------------------------------------------------------------------
18 | |
19 | | Once we have the application, we can handle the incoming request
20 | | through the kernel, and send the associated response back to
21 | | the client's browser allowing them to enjoy the creative
22 | | and wonderful application we have prepared for them.
23 | |
24 | */
25 |
26 | $app->run();
27 |
--------------------------------------------------------------------------------
/resources/lang/zh_CN/enums.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | use App\Enums\ResponseCode;
13 | use Jiannei\Enum\Laravel\Support\Enums\HttpStatusCode;
14 |
15 | return [
16 | ResponseCode::class => [
17 | // 标准 HTTP 状态码
18 | HttpStatusCode::HTTP_OK->value => '操作成功',
19 | HttpStatusCode::HTTP_UNAUTHORIZED->value => '授权失败',
20 |
21 | // 业务操作成功
22 | ResponseCode::SERVICE_REGISTER_SUCCESS->value => '注册成功',
23 | ResponseCode::SERVICE_LOGIN_SUCCESS->value => '登录成功',
24 |
25 | // 业务操作失败:授权业务
26 | ResponseCode::SERVICE_REGISTER_ERROR->value => '注册失败',
27 | ResponseCode::SERVICE_LOGIN_ERROR->value => '登录失败',
28 |
29 | // 客户端错误
30 | ResponseCode::CLIENT_PARAMETER_ERROR->value => '参数错误',
31 | ResponseCode::CLIENT_CREATED_ERROR->value => '数据已存在',
32 | ResponseCode::CLIENT_DELETED_ERROR->value => '数据不存在',
33 |
34 | // 服务端错误
35 | ResponseCode::SYSTEM_ERROR->value => '服务器错误',
36 | ResponseCode::SYSTEM_UNAVAILABLE->value => '服务器正在维护,暂不可用',
37 | ResponseCode::SYSTEM_CACHE_CONFIG_ERROR->value => '缓存配置错误',
38 | ResponseCode::SYSTEM_CACHE_MISSED_ERROR->value => '缓存未命中',
39 | ResponseCode::SYSTEM_CONFIG_ERROR->value => '系统配置错误',
40 | ],
41 | ];
42 |
--------------------------------------------------------------------------------
/resources/views/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiannei/lumen-api-starter/75deefb2e256fb334674f0e1717b27084f32bd49/resources/views/.gitkeep
--------------------------------------------------------------------------------
/routes/web.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | /*
13 | |--------------------------------------------------------------------------
14 | | Application Routes
15 | |--------------------------------------------------------------------------
16 | |
17 | | Here is where you can register all of the routes for an application.
18 | | It is a breeze. Simply tell Lumen the URIs it should respond to
19 | | and give it the Closure to call when that URI is requested.
20 | |
21 | */
22 |
23 | /* @var \Laravel\Lumen\Routing\Router $router */
24 |
25 | $router->get('/', function () use ($router) {
26 | return $router->app->version();
27 | });
28 |
29 | $router->get('users[/{paginate}]', 'UsersController@index');
30 |
31 | $router->group(['prefix' => 'auth'], function () use ($router) {
32 | $router->post('login', 'AuthController@login');
33 | $router->delete('logout', 'AuthController@logout');
34 | $router->put('refresh', 'AuthController@refresh');
35 | $router->get('me', 'AuthController@me');
36 | });
37 |
--------------------------------------------------------------------------------
/storage/app/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !data/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/storage/framework/cache/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/views/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/tests/ExampleTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Tests;
13 |
14 | class ExampleTest extends TestCase
15 | {
16 | /**
17 | * A basic test example.
18 | *
19 | * @return void
20 | */
21 | public function test_that_base_endpoint_returns_a_successful_response()
22 | {
23 | $this->get('/');
24 |
25 | $this->assertEquals(
26 | $this->app->version(), $this->response->getContent()
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/Feature/ExampleTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Tests\Feature;
13 |
14 | use Laravel\Lumen\Testing\DatabaseMigrations;
15 | use Tests\TestCase;
16 |
17 | class ExampleTest extends TestCase
18 | {
19 | // use DatabaseMigrations;
20 |
21 | /**
22 | * A basic test example.
23 | */
24 | public function testExample()
25 | {
26 | $this->get('/');
27 |
28 | $this->assertEquals(
29 | $this->app->version(),
30 | $this->response->getContent()
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Tests;
13 |
14 | use Laravel\Lumen\Testing\TestCase as BaseTestCase;
15 |
16 | abstract class TestCase extends BaseTestCase
17 | {
18 | /**
19 | * Creates the application.
20 | *
21 | * @return \Laravel\Lumen\Application
22 | */
23 | public function createApplication()
24 | {
25 | return require __DIR__.'/../bootstrap/app.php';
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/Traits/CreatesApplication.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Tests\Traits;
13 |
14 | trait CreatesApplication
15 | {
16 | /**
17 | * Creates the application.
18 | *
19 | * @return \Laravel\Lumen\Application
20 | */
21 | public function createApplication()
22 | {
23 | return require __DIR__.'/../../bootstrap/app.php';
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/Unit/ExampleTest.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * This source file is subject to the MIT license that is bundled
9 | * with this source code in the file LICENSE.
10 | */
11 |
12 | namespace Tests\Unit;
13 |
14 | use Tests\TestCase;
15 |
16 | class ExampleTest extends TestCase
17 | {
18 | /**
19 | * A basic test example.
20 | *
21 | * @return void
22 | */
23 | public function testBasicTest()
24 | {
25 | $this->assertTrue(true);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------