├── .env
├── .env.test
├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── bin
├── console
└── phpunit
├── composer.json
├── composer.lock
├── config
├── bootstrap.php
├── bundles.php
├── packages
│ ├── cache.yaml
│ ├── dev
│ │ ├── debug.yaml
│ │ ├── monolog.yaml
│ │ └── web_profiler.yaml
│ ├── doctrine.yaml
│ ├── doctrine_migrations.yaml
│ ├── fos_rest.yaml
│ ├── framework.yaml
│ ├── mailer.yaml
│ ├── notifier.yaml
│ ├── prod
│ │ ├── doctrine.yaml
│ │ ├── monolog.yaml
│ │ └── routing.yaml
│ ├── routing.yaml
│ ├── security.yaml
│ ├── sensio_framework_extra.yaml
│ ├── test
│ │ ├── framework.yaml
│ │ ├── monolog.yaml
│ │ ├── twig.yaml
│ │ ├── validator.yaml
│ │ └── web_profiler.yaml
│ ├── translation.yaml
│ ├── twig.yaml
│ └── validator.yaml
├── routes.yaml
├── routes
│ ├── annotations.yaml
│ └── dev
│ │ ├── framework.yaml
│ │ └── web_profiler.yaml
└── services.yaml
├── phpunit.xml.dist
├── public
└── index.php
├── src
├── Controller
│ ├── .gitignore
│ ├── AbstractApiController.php
│ ├── CartController.php
│ ├── CustomerController.php
│ └── ProductController.php
├── Entity
│ ├── .gitignore
│ ├── Cart.php
│ ├── Customer.php
│ └── Product.php
├── Form
│ └── Type
│ │ ├── CartType.php
│ │ ├── CustomerType.php
│ │ └── ProductType.php
├── Kernel.php
├── Migrations
│ └── Version20200515201045.php
└── Repository
│ └── .gitignore
├── symfony.lock
├── templates
└── base.html.twig
├── tests
└── bootstrap.php
└── translations
└── .gitignore
/.env:
--------------------------------------------------------------------------------
1 | # In all environments, the following files are loaded if they exist,
2 | # the latter taking precedence over the former:
3 | #
4 | # * .env contains default values for the environment variables needed by the app
5 | # * .env.local uncommitted file with local overrides
6 | # * .env.$APP_ENV committed environment-specific defaults
7 | # * .env.$APP_ENV.local uncommitted environment-specific overrides
8 | #
9 | # Real environment variables win over .env files.
10 | #
11 | # DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
12 | #
13 | # Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
14 | # https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
15 |
16 | ###> symfony/framework-bundle ###
17 | APP_ENV=dev
18 | APP_SECRET=50373636bdd097439dc76657d212924c
19 | #TRUSTED_PROXIES=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
20 | #TRUSTED_HOSTS='^(localhost|example\.com)$'
21 | ###< symfony/framework-bundle ###
22 |
23 | ###> symfony/mailer ###
24 | # MAILER_DSN=smtp://localhost
25 | ###< symfony/mailer ###
26 |
27 | ###> doctrine/doctrine-bundle ###
28 | # Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
29 | # For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
30 | # For a PostgreSQL database, use: "postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11&charset=utf8"
31 | # IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
32 | DATABASE_URL='postgres://sf_user:nopassword@postgres/test'
33 | ###< doctrine/doctrine-bundle ###
34 |
--------------------------------------------------------------------------------
/.env.test:
--------------------------------------------------------------------------------
1 | # define your env variables for the test env here
2 | KERNEL_CLASS='App\Kernel'
3 | APP_SECRET='$ecretf0rt3st'
4 | SYMFONY_DEPRECATIONS_HELPER=999999
5 | PANTHER_APP_ENV=panther
6 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | patreon: capcoding
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /public/bundles/
2 | /public/assets/
3 | /var/
4 | /vendor/
5 | .idea
6 |
7 | ###> phpunit/phpunit ###
8 | /phpunit.xml
9 | .phpunit.result.cache
10 | ###< phpunit/phpunit ###
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Cap Coding
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 | # How to build simple CRUD API service with Symfony 5 (for beginners)
2 |
3 | Please watch the whole video tutorial [here](https://youtu.be/tbXpX4dAqjg)
4 |
5 | Create a customer:
6 |
7 | ```sh
8 | curl --location --request POST 'http://localhost:8080/api/v1/customers' \
9 | --header 'Content-Type: application/json' \
10 | --data-raw '{
11 | "email": "test.email@gmail.com",
12 | "phoneNumber": "+49116012345678"
13 | }'
14 | ```
15 |
16 | Create a product:
17 |
18 | ```sh
19 | curl --location --request POST 'http://localhost:8080/api/v1/products' \
20 | --header 'Content-Type: application/json' \
21 | --data-raw '{
22 | "code": "test_code",
23 | "title": "Test title",
24 | "price": 1234
25 | }'
26 | ```
27 |
28 | Create a cart:
29 |
30 | ```sh
31 | curl --location --request POST 'http://localhost:8080/api/v1/customers/cart' \
32 | --header 'Content-Type: application/json' \
33 | --data-raw '{
34 | "customer": 1,
35 | "products": [
36 | 1
37 | ],
38 | "dateTime": "2020-08-05 12:15:00"
39 | }'
40 | ```
41 |
42 |
43 | # Other video tutorials
44 |
45 | ## Code faster with Github Copilot
46 |
47 | There is a [video](https://youtu.be/qyxJXNNvd70)
48 |
49 | ## Create a classic website using Symfony 5
50 |
51 | There is a [video](https://youtu.be/svAxl6U8akQ)
52 |
53 | ## Delay "heavy" tasks in Symfony with component Messenger
54 |
55 | There is a [video](https://youtu.be/UHlA5nHdCmw)
56 |
57 | ## Delay heavy tasks in Symfony with kernel.terminate event to decrease response time
58 |
59 | There is a [video](https://youtu.be/HrQme9KUlUg)
60 |
61 | ## Create Symfony 5 project with Docker and Postgres
62 |
63 | There is a [video](https://youtu.be/4UrPI6Y3BWA)
64 |
65 | ## Design pattern "Chain of responsibility" (Symfony implementation)
66 |
67 | There is a [video](https://youtu.be/3KQlubIv684)
68 |
69 | ## How to use data transfer objects (DTO) in Symfony API application
70 |
71 | There is a [branch](https://github.com/Cap-Coding/symfony_api/tree/data_transfer_objects) and here is a [video](https://youtu.be/XxIhzgGv214)
72 |
73 | ## How to build simple CRUD API service with Symfony 5 (for beginners)
74 |
75 | There is a [branch](https://github.com/Cap-Coding/symfony_api/tree/crud_api) and here is a [video](https://youtu.be/tbXpX4dAqjg)
76 |
77 | ## How to use Symfony Form Events in API service
78 |
79 | There is a [video](https://youtu.be/lLwx96DA_Ww)
80 |
81 | ## How to use object factories with Symfony Forms
82 |
83 | There is a [video](https://youtu.be/chgvsi6TWM8)
84 |
85 | ## Dockerize WordPress
86 |
87 | There is a [video](https://youtu.be/coqucs1UhMY)
88 |
89 | ## Get trusted SSL certificate (https) for free with Let's Encrypt and Certbot
90 |
91 | There is a [video](https://youtu.be/nFDk43tAKFQ)
92 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | getParameterOption(['--env', '-e'], null, true)) {
23 | putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
24 | }
25 |
26 | if ($input->hasParameterOption('--no-debug', true)) {
27 | putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
28 | }
29 |
30 | require dirname(__DIR__).'/config/bootstrap.php';
31 |
32 | if ($_SERVER['APP_DEBUG']) {
33 | umask(0000);
34 |
35 | if (class_exists(Debug::class)) {
36 | Debug::enable();
37 | }
38 | }
39 |
40 | $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
41 | $application = new Application($kernel);
42 | $application->run($input);
43 |
--------------------------------------------------------------------------------
/bin/phpunit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | =1.2)
13 | if (is_array($env = @include dirname(__DIR__).'/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) {
14 | (new Dotenv(false))->populate($env);
15 | } else {
16 | // load all the .env files
17 | (new Dotenv(false))->loadEnv(dirname(__DIR__).'/.env');
18 | }
19 |
20 | $_SERVER += $_ENV;
21 | $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
22 | $_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
23 | $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
24 |
--------------------------------------------------------------------------------
/config/bundles.php:
--------------------------------------------------------------------------------
1 | ['all' => true],
5 | Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
6 | Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
7 | Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
8 | Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
9 | Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
10 | Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
11 | Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
12 | Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
13 | Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
14 | Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
15 | FOS\RestBundle\FOSRestBundle::class => ['all' => true],
16 | ];
17 |
--------------------------------------------------------------------------------
/config/packages/cache.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | cache:
3 | # Unique name of your app: used to compute stable namespaces for cache keys.
4 | #prefix_seed: your_vendor_name/app_name
5 |
6 | # The "app" cache stores to the filesystem by default.
7 | # The data in this cache should persist between deploys.
8 | # Other options include:
9 |
10 | # Redis
11 | #app: cache.adapter.redis
12 | #default_redis_provider: redis://localhost
13 |
14 | # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
15 | #app: cache.adapter.apcu
16 |
17 | # Namespaced pools use the above "app" backend by default
18 | #pools:
19 | #my.dedicated.cache: null
20 |
--------------------------------------------------------------------------------
/config/packages/dev/debug.yaml:
--------------------------------------------------------------------------------
1 | debug:
2 | # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
3 | # See the "server:dump" command to start a new server.
4 | dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
5 |
--------------------------------------------------------------------------------
/config/packages/dev/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: debug
7 | channels: ["!event"]
8 | # uncomment to get logging in your browser
9 | # you may have to allow bigger header sizes in your Web server configuration
10 | #firephp:
11 | # type: firephp
12 | # level: info
13 | #chromephp:
14 | # type: chromephp
15 | # level: info
16 | console:
17 | type: console
18 | process_psr_3_messages: false
19 | channels: ["!event", "!doctrine", "!console"]
20 |
--------------------------------------------------------------------------------
/config/packages/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: true
3 | intercept_redirects: false
4 |
5 | framework:
6 | profiler: { only_exceptions: false }
7 |
--------------------------------------------------------------------------------
/config/packages/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | dbal:
3 | driver: 'pdo_pgsql'
4 | server_version: '12.2'
5 | charset: utf8
6 | url: '%env(resolve:DATABASE_URL)%'
7 | orm:
8 | auto_generate_proxy_classes: true
9 | naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
10 | auto_mapping: true
11 | mappings:
12 | App:
13 | is_bundle: false
14 | type: annotation
15 | dir: '%kernel.project_dir%/src/Entity'
16 | prefix: 'App\Entity'
17 | alias: App
18 |
--------------------------------------------------------------------------------
/config/packages/doctrine_migrations.yaml:
--------------------------------------------------------------------------------
1 | doctrine_migrations:
2 | migrations_paths:
3 | # namespace is arbitrary but should be different from App\Migrations
4 | # as migrations classes should NOT be autoloaded
5 | 'DoctrineMigrations': '%kernel.project_dir%/src/Migrations'
6 |
--------------------------------------------------------------------------------
/config/packages/fos_rest.yaml:
--------------------------------------------------------------------------------
1 | # Read the documentation: https://symfony.com/doc/master/bundles/FOSRestBundle/index.html
2 | fos_rest:
3 | body_listener:
4 | enabled: true
5 | # param_fetcher_listener: true
6 | # allowed_methods_listener: true
7 | # routing_loader: true
8 | # view:
9 | # view_response_listener: true
10 | # exception:
11 | # codes:
12 | # App\Exception\MyException: 403
13 | # messages:
14 | # App\Exception\MyException: Forbidden area.
15 | format_listener:
16 | rules:
17 | - { path: ^/api, prefer_extension: true, fallback_format: json, priorities: [ json ] }
18 |
--------------------------------------------------------------------------------
/config/packages/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | secret: '%env(APP_SECRET)%'
3 | #csrf_protection: true
4 | #http_method_override: true
5 |
6 | # Enables session support. Note that the session will ONLY be started if you read or write from it.
7 | # Remove or comment this section to explicitly disable session support.
8 | session:
9 | handler_id: null
10 | cookie_secure: auto
11 | cookie_samesite: lax
12 |
13 | #esi: true
14 | #fragments: true
15 | php_errors:
16 | log: true
17 |
--------------------------------------------------------------------------------
/config/packages/mailer.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | mailer:
3 | dsn: '%env(MAILER_DSN)%'
4 |
--------------------------------------------------------------------------------
/config/packages/notifier.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | notifier:
3 | #chatter_transports:
4 | # slack: '%env(SLACK_DSN)%'
5 | # telegram: '%env(TELEGRAM_DSN)%'
6 | #texter_transports:
7 | # twilio: '%env(TWILIO_DSN)%'
8 | # nexmo: '%env(NEXMO_DSN)%'
9 | channel_policy:
10 | # use chat/slack, chat/telegram, sms/twilio or sms/nexmo
11 | urgent: ['email']
12 | high: ['email']
13 | medium: ['email']
14 | low: ['email']
15 | admin_recipients:
16 | - { email: admin@example.com }
17 |
--------------------------------------------------------------------------------
/config/packages/prod/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | orm:
3 | auto_generate_proxy_classes: false
4 | metadata_cache_driver:
5 | type: pool
6 | pool: doctrine.system_cache_pool
7 | query_cache_driver:
8 | type: pool
9 | pool: doctrine.system_cache_pool
10 | result_cache_driver:
11 | type: pool
12 | pool: doctrine.result_cache_pool
13 |
14 | framework:
15 | cache:
16 | pools:
17 | doctrine.result_cache_pool:
18 | adapter: cache.app
19 | doctrine.system_cache_pool:
20 | adapter: cache.system
21 |
--------------------------------------------------------------------------------
/config/packages/prod/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: fingers_crossed
5 | action_level: error
6 | handler: nested
7 | excluded_http_codes: [404, 405]
8 | buffer_size: 50 # How many messages should be saved? Prevent memory leaks
9 | nested:
10 | type: stream
11 | path: "%kernel.logs_dir%/%kernel.environment%.log"
12 | level: debug
13 | console:
14 | type: console
15 | process_psr_3_messages: false
16 | channels: ["!event", "!doctrine"]
17 |
18 | # Uncomment to log deprecations
19 | #deprecation:
20 | # type: stream
21 | # path: "%kernel.logs_dir%/%kernel.environment%.deprecations.log"
22 | #deprecation_filter:
23 | # type: filter
24 | # handler: deprecation
25 | # max_level: info
26 | # channels: ["php"]
27 |
--------------------------------------------------------------------------------
/config/packages/prod/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: null
4 |
--------------------------------------------------------------------------------
/config/packages/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | utf8: true
4 |
--------------------------------------------------------------------------------
/config/packages/security.yaml:
--------------------------------------------------------------------------------
1 | security:
2 | # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
3 | providers:
4 | users_in_memory: { memory: null }
5 | firewalls:
6 | dev:
7 | pattern: ^/(_(profiler|wdt)|css|images|js)/
8 | security: false
9 | main:
10 | anonymous: lazy
11 | provider: users_in_memory
12 |
13 | # activate different ways to authenticate
14 | # https://symfony.com/doc/current/security.html#firewalls-authentication
15 |
16 | # https://symfony.com/doc/current/security/impersonating_user.html
17 | # switch_user: true
18 |
19 | # Easy way to control access for large sections of your site
20 | # Note: Only the *first* access control that matches will be used
21 | access_control:
22 | # - { path: ^/admin, roles: ROLE_ADMIN }
23 | # - { path: ^/profile, roles: ROLE_USER }
24 |
--------------------------------------------------------------------------------
/config/packages/sensio_framework_extra.yaml:
--------------------------------------------------------------------------------
1 | sensio_framework_extra:
2 | router:
3 | annotations: false
4 |
--------------------------------------------------------------------------------
/config/packages/test/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | test: true
3 | session:
4 | storage_id: session.storage.mock_file
5 |
--------------------------------------------------------------------------------
/config/packages/test/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: fingers_crossed
5 | action_level: error
6 | handler: nested
7 | excluded_http_codes: [404, 405]
8 | channels: ["!event"]
9 | nested:
10 | type: stream
11 | path: "%kernel.logs_dir%/%kernel.environment%.log"
12 | level: debug
13 |
--------------------------------------------------------------------------------
/config/packages/test/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | strict_variables: true
3 |
--------------------------------------------------------------------------------
/config/packages/test/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | not_compromised_password: false
4 |
--------------------------------------------------------------------------------
/config/packages/test/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: false
3 | intercept_redirects: false
4 |
5 | framework:
6 | profiler: { collect: false }
7 |
--------------------------------------------------------------------------------
/config/packages/translation.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | default_locale: en
3 | translator:
4 | default_path: '%kernel.project_dir%/translations'
5 | fallbacks:
6 | - en
7 |
--------------------------------------------------------------------------------
/config/packages/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | default_path: '%kernel.project_dir%/templates'
3 |
--------------------------------------------------------------------------------
/config/packages/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | email_validation_mode: html5
4 |
5 | # Enables validator auto-mapping support.
6 | # For instance, basic validation constraints will be inferred from Doctrine's metadata.
7 | #auto_mapping:
8 | # App\Entity\: []
9 |
--------------------------------------------------------------------------------
/config/routes.yaml:
--------------------------------------------------------------------------------
1 | customer_list:
2 | path: /api/v1/customers
3 | controller: App\Controller\CustomerController:indexAction
4 | methods: [GET]
5 |
6 | customer_create:
7 | path: /api/v1/customers
8 | controller: App\Controller\CustomerController:createAction
9 | methods: [POST]
10 |
11 | product_list:
12 | path: /api/v1/products
13 | controller: App\Controller\ProductController:indexAction
14 | methods: [GET]
15 |
16 | product_create:
17 | path: /api/v1/products
18 | controller: App\Controller\ProductController:createAction
19 | methods: [POST]
20 |
21 | cart_show:
22 | path: /api/v1/customers/{id}/cart
23 | controller: App\Controller\CartController:showAction
24 | methods: [GET]
25 | requirements:
26 | id: '\d+'
27 |
28 | cart_create:
29 | path: /api/v1/customers/cart
30 | controller: App\Controller\CartController:createAction
31 | methods: [POST]
32 |
33 | cart_update:
34 | path: /api/v1/customers/{customerId}/cart
35 | controller: App\Controller\CartController:updateAction
36 | methods: [PATCH]
37 | requirements:
38 | customerId: '\d+'
39 |
40 | cart_delete:
41 | path: /api/v1/customers/{customerId}/cart/{cartId}
42 | controller: App\Controller\CartController:deleteAction
43 | methods: [DELETE]
44 | requirements:
45 | customerId: '\d+'
46 | cartId: '\d+'
47 |
48 |
--------------------------------------------------------------------------------
/config/routes/annotations.yaml:
--------------------------------------------------------------------------------
1 | controllers:
2 | resource: ../../src/Controller/
3 | type: annotation
4 |
5 | kernel:
6 | resource: ../../src/Kernel.php
7 | type: annotation
8 |
--------------------------------------------------------------------------------
/config/routes/dev/framework.yaml:
--------------------------------------------------------------------------------
1 | _errors:
2 | resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
3 | prefix: /_error
4 |
--------------------------------------------------------------------------------
/config/routes/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler_wdt:
2 | resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
3 | prefix: /_wdt
4 |
5 | web_profiler_profiler:
6 | resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
7 | prefix: /_profiler
8 |
--------------------------------------------------------------------------------
/config/services.yaml:
--------------------------------------------------------------------------------
1 | # This file is the entry point to configure your own services.
2 | # Files in the packages/ subdirectory configure your dependencies.
3 |
4 | # Put parameters here that don't need to change on each machine where the app is deployed
5 | # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
6 | parameters:
7 |
8 | services:
9 | # default configuration for services in *this* file
10 | _defaults:
11 | autowire: true # Automatically injects dependencies in your services.
12 | autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
13 |
14 | # makes classes in src/ available to be used as services
15 | # this creates a service per class whose id is the fully-qualified class name
16 | App\:
17 | resource: '../src/*'
18 | exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
19 |
20 | # controllers are imported separately to make sure services can be injected
21 | # as action arguments even if you don't extend any base controller class
22 | App\Controller\:
23 | resource: '../src/Controller'
24 | tags: ['controller.service_arguments']
25 |
26 | # add more service definitions when explicit configuration is needed
27 | # please note that last definitions always *replace* previous ones
28 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |