mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 06:37:55 +08:00 
			
		
		
		
	Add rest-versioning.md to translate into Russian [skip ci]
This commit is contained in:
		
							
								
								
									
										107
									
								
								docs/guide-ru/rest-versioning.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								docs/guide-ru/rest-versioning.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					Versioning
 | 
				
			||||||
 | 
					==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Your APIs should be versioned. Unlike Web applications which you have full control on both client side and server side
 | 
				
			||||||
 | 
					code, for APIs you usually do not have control of the client code that consumes the APIs. Therefore, backward
 | 
				
			||||||
 | 
					compatibility (BC) of the APIs should be maintained whenever possible, and if some BC-breaking changes must be
 | 
				
			||||||
 | 
					introduced to the APIs, you should bump up the version number. You may refer to [Semantic Versioning](http://semver.org/)
 | 
				
			||||||
 | 
					for more information about designing the version numbers of your APIs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Regarding how to implement API versioning, a common practice is to embed the version number in the API URLs.
 | 
				
			||||||
 | 
					For example, `http://example.com/v1/users` stands for `/users` API of version 1. Another method of API versioning
 | 
				
			||||||
 | 
					which gains momentum recently is to put version numbers in the HTTP request headers, typically through the `Accept` header,
 | 
				
			||||||
 | 
					like the following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					// via a parameter
 | 
				
			||||||
 | 
					Accept: application/json; version=v1
 | 
				
			||||||
 | 
					// via a vendor content type
 | 
				
			||||||
 | 
					Accept: application/vnd.company.myapp-v1+json
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Both methods have pros and cons, and there are a lot of debates about them. Below we describe a practical strategy
 | 
				
			||||||
 | 
					of API versioning that is kind of a mix of these two methods:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Put each major version of API implementation in a separate module whose ID is the major version number (e.g. `v1`, `v2`).
 | 
				
			||||||
 | 
					  Naturally, the API URLs will contain major version numbers.
 | 
				
			||||||
 | 
					* Within each major version (and thus within the corresponding module), use the `Accept` HTTP request header
 | 
				
			||||||
 | 
					  to determine the minor version number and write conditional code to respond to the minor versions accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For each module serving a major version, it should include the resource classes and the controller classes
 | 
				
			||||||
 | 
					serving for that specific version. To better separate code responsibility, you may keep a common set of
 | 
				
			||||||
 | 
					base resource and controller classes, and subclass them in each individual version module. Within the subclasses,
 | 
				
			||||||
 | 
					implement the concrete code such as `Model::fields()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Your code may be organized like the following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					api/
 | 
				
			||||||
 | 
					    common/
 | 
				
			||||||
 | 
					        controllers/
 | 
				
			||||||
 | 
					            UserController.php
 | 
				
			||||||
 | 
					            PostController.php
 | 
				
			||||||
 | 
					        models/
 | 
				
			||||||
 | 
					            User.php
 | 
				
			||||||
 | 
					            Post.php
 | 
				
			||||||
 | 
					    modules/
 | 
				
			||||||
 | 
					        v1/
 | 
				
			||||||
 | 
					            controllers/
 | 
				
			||||||
 | 
					                UserController.php
 | 
				
			||||||
 | 
					                PostController.php
 | 
				
			||||||
 | 
					            models/
 | 
				
			||||||
 | 
					                User.php
 | 
				
			||||||
 | 
					                Post.php
 | 
				
			||||||
 | 
					        v2/
 | 
				
			||||||
 | 
					            controllers/
 | 
				
			||||||
 | 
					                UserController.php
 | 
				
			||||||
 | 
					                PostController.php
 | 
				
			||||||
 | 
					            models/
 | 
				
			||||||
 | 
					                User.php
 | 
				
			||||||
 | 
					                Post.php
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Your application configuration would look like:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```php
 | 
				
			||||||
 | 
					return [
 | 
				
			||||||
 | 
					    'modules' => [
 | 
				
			||||||
 | 
					        'v1' => [
 | 
				
			||||||
 | 
					            'basePath' => '@app/modules/v1',
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        'v2' => [
 | 
				
			||||||
 | 
					            'basePath' => '@app/modules/v2',
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    'components' => [
 | 
				
			||||||
 | 
					        'urlManager' => [
 | 
				
			||||||
 | 
					            'enablePrettyUrl' => true,
 | 
				
			||||||
 | 
					            'enableStrictParsing' => true,
 | 
				
			||||||
 | 
					            'showScriptName' => false,
 | 
				
			||||||
 | 
					            'rules' => [
 | 
				
			||||||
 | 
					                ['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user', 'v1/post']],
 | 
				
			||||||
 | 
					                ['class' => 'yii\rest\UrlRule', 'controller' => ['v2/user', 'v2/post']],
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As a result, `http://example.com/v1/users` will return the list of users in version 1, while
 | 
				
			||||||
 | 
					`http://example.com/v2/users` will return version 2 users.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Using modules, code for different major versions can be well isolated. And it is still possible
 | 
				
			||||||
 | 
					to reuse code across modules via common base classes and other shared classes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To deal with minor version numbers, you may take advantage of the content negotiation
 | 
				
			||||||
 | 
					feature provided by the [[yii\filters\ContentNegotiator|contentNegotiator]] behavior. The `contentNegotiator`
 | 
				
			||||||
 | 
					behavior will set the [[yii\web\Response::acceptParams]] property when it determines which
 | 
				
			||||||
 | 
					content type to support.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, if a request is sent with the HTTP header `Accept: application/json; version=v1`,
 | 
				
			||||||
 | 
					after content negotiation, [[yii\web\Response::acceptParams]] will contain the value `['version' => 'v1']`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Based on the version information in `acceptParams`, you may write conditional code in places
 | 
				
			||||||
 | 
					such as actions, resource classes, serializers, etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Since minor versions require maintaining backward compatibility, hopefully there are not much
 | 
				
			||||||
 | 
					version checks in your code. Otherwise, chances are that you may need to create a new major version.
 | 
				
			||||||
		Reference in New Issue
	
	Block a user