request_migrations 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9ade55e7b503c08190a46b58d68dfc35f619c9cf949c12ef98e7cb58548d2b6
|
4
|
+
data.tar.gz: 0e2a334989b6d79ec9296e9ef3c5866b42c0121e87cc2d9fa219835ff6e225e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15e401e45c34e2054505e2c85968cbe7b81b20b7e987b2034acce71ece1d8fb48ebf5906a2166c957cd6bbdb3f3a8e7fccdab66e27bccf1f1960288efa748f4d
|
7
|
+
data.tar.gz: 97a1233a8c01c6d818e5682b06164bf15d6e75f890a6aebbc0188712e0fa996d0d40b48f1d72e83f478573d0e8bc97350f7450cd254bbf5a1cb0efe1a9992ba1
|
data/README.md
CHANGED
@@ -3,12 +3,15 @@
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/request_migrations.svg)](https://badge.fury.io/rb/request_migrations)
|
4
4
|
|
5
5
|
**Make breaking API changes without breaking things!** Use `request_migrations` to craft
|
6
|
-
backwards-compatible migrations for API requests, responses, and more. This
|
7
|
-
|
6
|
+
backwards-compatible migrations for API requests, responses, and more. This gem was extracted
|
7
|
+
from [Keygen](https://keygen.sh) and is being used in production to serve millions of API
|
8
|
+
requests per day.
|
9
|
+
|
10
|
+
![request_migrations diagram](https://user-images.githubusercontent.com/6979737/175406011-883b2671-152c-4e6e-8716-d6c4c3ed2676.png)
|
8
11
|
|
9
12
|
Sponsored by:
|
10
13
|
|
11
|
-
[![Keygen logo](https://
|
14
|
+
[![Keygen logo](https://user-images.githubusercontent.com/6979737/175406169-bd8bf064-7343-4bd1-94b7-a773ecec07b8.png)](https://keygen.sh)
|
12
15
|
|
13
16
|
_A software licensing and distribution API built for developers._
|
14
17
|
|
@@ -539,6 +542,30 @@ class V1x0::UsersController
|
|
539
542
|
end
|
540
543
|
```
|
541
544
|
|
545
|
+
### Avoid migrate for request migrations
|
546
|
+
|
547
|
+
Avoid using `migrate` for request migrations. If you do, one-off migrations, e.g. for webhooks
|
548
|
+
will apply the request migrations, which may erroneously produce bad output, or even undo a
|
549
|
+
response migration. Instead, keep all request migration logic, e.g. transforming params,
|
550
|
+
inside of the `request` block.
|
551
|
+
|
552
|
+
```ruby
|
553
|
+
class SomeMigration < RequestMigrations::Migration
|
554
|
+
# Bad (side-effects for one-off migrations)
|
555
|
+
migrate do |params|
|
556
|
+
params[:foo] = params.delete(:bar)
|
557
|
+
end
|
558
|
+
|
559
|
+
request do |req|
|
560
|
+
migrate!(req.params)
|
561
|
+
end
|
562
|
+
|
563
|
+
# Good
|
564
|
+
request do |req|
|
565
|
+
req.params[:foo] = req.params.delete(:bar)
|
566
|
+
end
|
567
|
+
end
|
568
|
+
```
|
542
569
|
|
543
570
|
### Avoid routing contraints
|
544
571
|
|
@@ -15,7 +15,7 @@ module RequestMigrations
|
|
15
15
|
def migrate!
|
16
16
|
logger.debug { "Migrating from #{current_version} to #{target_version} (#{migrations.size} potential migrations)" }
|
17
17
|
|
18
|
-
migrations.each_with_index { |migration, i|
|
18
|
+
migrations.reverse.each_with_index { |migration, i|
|
19
19
|
logger.debug { "Applying migration #{migration} (#{i + 1}/#{migrations.size})" }
|
20
20
|
|
21
21
|
migration.new.migrate_request!(request)
|
@@ -1,6 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RequestMigrations
|
4
|
+
##
|
5
|
+
# Migration represents a migration for a specific version.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# class CombineNamesForUserMigration < RequestMigrations::Migration
|
9
|
+
# description %(transforms a user's first and last name to a combined name attribute)
|
10
|
+
#
|
11
|
+
# migrate if: -> data { data in type: 'user' } do |data|
|
12
|
+
# first_name = data.delete(:first_name)
|
13
|
+
# last_name = data.delete(:last_name)
|
14
|
+
#
|
15
|
+
# data[:name] = "#{first_name} #{last_name}"
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# response if: -> res { res.successful? && res.request.params in controller: 'api/v1/users',
|
19
|
+
# action: 'show' } do |res|
|
20
|
+
# data = JSON.parse(res.body, symbolize_names: true)
|
21
|
+
#
|
22
|
+
# migrate!(data)
|
23
|
+
#
|
24
|
+
# res.body = JSON.generate(data)
|
25
|
+
# end
|
26
|
+
# end
|
4
27
|
class Migration
|
5
28
|
##
|
6
29
|
# @private
|
@@ -37,11 +37,12 @@ module RequestMigrations
|
|
37
37
|
|
38
38
|
def logger = RequestMigrations.logger
|
39
39
|
|
40
|
-
# TODO(ezekg) These should be sorted.
|
41
40
|
def migrations
|
42
41
|
@migrations ||=
|
43
42
|
RequestMigrations.config.versions
|
44
43
|
.filter { |(version, _)| Version.new(version).between?(target_version, current_version) }
|
44
|
+
.sort
|
45
|
+
.reverse
|
45
46
|
.flat_map { |(_, migrations)| migrations }
|
46
47
|
.map { |migration|
|
47
48
|
case migration
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: request_migrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zeke Gabrielse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06-
|
11
|
+
date: 2022-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|