opaque_id 1.1.0 โ 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +50 -0
- data/CODE_OF_CONDUCT.md +11 -11
- data/README.md +82 -0
- data/docs/.gitignore +5 -0
- data/docs/404.html +25 -0
- data/docs/Gemfile +31 -0
- data/docs/Gemfile.lock +335 -0
- data/docs/_config.yml +162 -0
- data/docs/_data/navigation.yml +132 -0
- data/docs/_includes/footer_custom.html +8 -0
- data/docs/_includes/head_custom.html +67 -0
- data/docs/algorithms.md +409 -0
- data/docs/alphabets.md +521 -0
- data/docs/api-reference.md +594 -0
- data/docs/assets/css/custom.scss +798 -0
- data/docs/assets/images/favicon.svg +17 -0
- data/docs/assets/images/og-image.svg +65 -0
- data/docs/configuration.md +548 -0
- data/docs/development.md +567 -0
- data/docs/getting-started.md +256 -0
- data/docs/index.md +132 -0
- data/docs/installation.md +377 -0
- data/docs/performance.md +488 -0
- data/docs/robots.txt +11 -0
- data/docs/security.md +598 -0
- data/docs/usage.md +414 -0
- data/docs/use-cases.md +569 -0
- data/lib/generators/opaque_id/install_generator.rb +38 -23
- data/lib/opaque_id/version.rb +1 -1
- data/tasks/0003-prd-documentation-site.md +191 -0
- data/tasks/tasks-0003-prd-documentation-site.md +84 -0
- metadata +27 -2
- data/sig/opaque_id.rbs +0 -4
@@ -0,0 +1,256 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Getting Started
|
4
|
+
nav_order: 2
|
5
|
+
description: "Quick setup and basic usage guide for OpaqueId"
|
6
|
+
permalink: /getting-started/
|
7
|
+
---
|
8
|
+
|
9
|
+
# Getting Started
|
10
|
+
|
11
|
+
This guide will help you get up and running with OpaqueId in your Rails application. We'll cover installation, basic setup, and common usage patterns.
|
12
|
+
|
13
|
+
## Prerequisites
|
14
|
+
|
15
|
+
Before you begin, ensure you have:
|
16
|
+
|
17
|
+
- **Ruby 3.2+** - OpaqueId requires modern Ruby features
|
18
|
+
- **Rails 8.0+** - Built for the latest Rails version
|
19
|
+
- **ActiveRecord 8.0+** - For model integration
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
### Step 1: Add to Gemfile
|
24
|
+
|
25
|
+
Add OpaqueId to your application's Gemfile:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
gem 'opaque_id'
|
29
|
+
```
|
30
|
+
|
31
|
+
Then run:
|
32
|
+
|
33
|
+
```bash
|
34
|
+
bundle install
|
35
|
+
```
|
36
|
+
|
37
|
+
### Step 2: Generate Migration and Update Model
|
38
|
+
|
39
|
+
Use the Rails generator to set up OpaqueId for a specific model:
|
40
|
+
|
41
|
+
```bash
|
42
|
+
rails generate opaque_id:install User
|
43
|
+
```
|
44
|
+
|
45
|
+
This command will:
|
46
|
+
|
47
|
+
- Create a migration to add the `opaque_id` column
|
48
|
+
- Add a unique index on the `opaque_id` column
|
49
|
+
- Include the `OpaqueId::Model` concern in your model
|
50
|
+
|
51
|
+
### Step 3: Run Migration
|
52
|
+
|
53
|
+
Execute the migration:
|
54
|
+
|
55
|
+
```bash
|
56
|
+
rails db:migrate
|
57
|
+
```
|
58
|
+
|
59
|
+
### Step 4: Verify Setup
|
60
|
+
|
61
|
+
Check that your model has been updated correctly:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
# app/models/user.rb
|
65
|
+
class User < ApplicationRecord
|
66
|
+
include OpaqueId::Model
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
## Basic Usage
|
71
|
+
|
72
|
+
### Creating Records
|
73
|
+
|
74
|
+
Once set up, OpaqueId automatically generates opaque IDs when you create new records:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
# Create a new user
|
78
|
+
user = User.create!(name: "John Doe", email: "john@example.com")
|
79
|
+
|
80
|
+
# The opaque_id is automatically generated
|
81
|
+
puts user.opaque_id
|
82
|
+
# => "V1StGXR8_Z5jdHi6B-myT"
|
83
|
+
```
|
84
|
+
|
85
|
+
### Finding Records
|
86
|
+
|
87
|
+
Use the provided finder methods to locate records by their opaque ID:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
# Find by opaque_id (returns nil if not found)
|
91
|
+
user = User.find_by_opaque_id("V1StGXR8_Z5jdHi6B-myT")
|
92
|
+
|
93
|
+
# Find by opaque_id (raises exception if not found)
|
94
|
+
user = User.find_by_opaque_id!("V1StGXR8_Z5jdHi6B-myT")
|
95
|
+
```
|
96
|
+
|
97
|
+
### Standalone ID Generation
|
98
|
+
|
99
|
+
You can also generate opaque IDs without ActiveRecord:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
# Generate a default opaque ID (21 characters, alphanumeric)
|
103
|
+
id = OpaqueId.generate
|
104
|
+
# => "V1StGXR8_Z5jdHi6B-myT"
|
105
|
+
|
106
|
+
# Generate with custom length
|
107
|
+
id = OpaqueId.generate(size: 10)
|
108
|
+
# => "V1StGXR8_Z5"
|
109
|
+
|
110
|
+
# Generate with custom alphabet
|
111
|
+
id = OpaqueId.generate(alphabet: OpaqueId::STANDARD_ALPHABET)
|
112
|
+
# => "V1StGXR8_Z5jdHi6B-myT"
|
113
|
+
```
|
114
|
+
|
115
|
+
## Common Patterns
|
116
|
+
|
117
|
+
### API Endpoints
|
118
|
+
|
119
|
+
Use opaque IDs in your API endpoints for better security:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
# routes.rb
|
123
|
+
resources :users, param: :opaque_id
|
124
|
+
|
125
|
+
# controller
|
126
|
+
class UsersController < ApplicationController
|
127
|
+
def show
|
128
|
+
@user = User.find_by_opaque_id!(params[:id])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
### URL Generation
|
134
|
+
|
135
|
+
Generate URLs using opaque IDs:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
# Instead of exposing internal IDs
|
139
|
+
user_path(user) # => /users/123
|
140
|
+
|
141
|
+
# Use opaque IDs
|
142
|
+
user_path(user.opaque_id) # => /users/V1StGXR8_Z5jdHi6B-myT
|
143
|
+
```
|
144
|
+
|
145
|
+
### Custom Column Names
|
146
|
+
|
147
|
+
If you prefer a different column name, specify it during generation:
|
148
|
+
|
149
|
+
```bash
|
150
|
+
rails generate opaque_id:install User --column-name=public_id
|
151
|
+
```
|
152
|
+
|
153
|
+
This will:
|
154
|
+
|
155
|
+
- Create a `public_id` column instead of `opaque_id`
|
156
|
+
- Add the configuration to your model automatically
|
157
|
+
|
158
|
+
## Configuration Options
|
159
|
+
|
160
|
+
OpaqueId is highly configurable. Here are the most common options:
|
161
|
+
|
162
|
+
### Model-Level Configuration
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
class User < ApplicationRecord
|
166
|
+
include OpaqueId::Model
|
167
|
+
|
168
|
+
# Custom column name
|
169
|
+
self.opaque_id_column = :public_id
|
170
|
+
|
171
|
+
# Custom length (default: 21)
|
172
|
+
self.opaque_id_length = 15
|
173
|
+
|
174
|
+
# Custom alphabet (default: ALPHANUMERIC_ALPHABET)
|
175
|
+
self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
|
176
|
+
|
177
|
+
# Require letter start (default: false)
|
178
|
+
self.opaque_id_require_letter_start = true
|
179
|
+
|
180
|
+
# Max retry attempts for collision handling (default: 3)
|
181
|
+
self.opaque_id_max_retry = 5
|
182
|
+
end
|
183
|
+
```
|
184
|
+
|
185
|
+
### Global Configuration
|
186
|
+
|
187
|
+
You can also configure OpaqueId globally in an initializer:
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
# config/initializers/opaque_id.rb
|
191
|
+
OpaqueId.configure do |config|
|
192
|
+
config.default_length = 15
|
193
|
+
config.default_alphabet = OpaqueId::STANDARD_ALPHABET
|
194
|
+
end
|
195
|
+
```
|
196
|
+
|
197
|
+
## Built-in Alphabets
|
198
|
+
|
199
|
+
OpaqueId comes with two pre-configured alphabets:
|
200
|
+
|
201
|
+
### ALPHANUMERIC_ALPHABET (Default)
|
202
|
+
|
203
|
+
- **Characters**: `A-Z`, `a-z`, `0-9` (62 characters)
|
204
|
+
- **Use case**: General purpose, URL-safe
|
205
|
+
- **Example**: `V1StGXR8_Z5jdHi6B-myT`
|
206
|
+
|
207
|
+
### STANDARD_ALPHABET
|
208
|
+
|
209
|
+
- **Characters**: `A-Z`, `a-z`, `0-9`, `-`, `_` (64 characters)
|
210
|
+
- **Use case**: When you need the fastest generation
|
211
|
+
- **Example**: `V1StGXR8_Z5jdHi6B-myT`
|
212
|
+
|
213
|
+
## Error Handling
|
214
|
+
|
215
|
+
OpaqueId provides comprehensive error handling:
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
begin
|
219
|
+
user = User.create!(name: "John Doe")
|
220
|
+
rescue OpaqueId::GenerationError => e
|
221
|
+
# Handle ID generation failure (very rare)
|
222
|
+
Rails.logger.error "Failed to generate opaque ID: #{e.message}"
|
223
|
+
end
|
224
|
+
```
|
225
|
+
|
226
|
+
## Next Steps
|
227
|
+
|
228
|
+
Now that you have OpaqueId set up, you might want to explore:
|
229
|
+
|
230
|
+
- [Installation](installation.md) - Detailed installation guide
|
231
|
+
- [Usage](usage.md) - Comprehensive usage examples
|
232
|
+
- [Configuration](configuration.md) - Detailed configuration guide
|
233
|
+
- [Alphabets](alphabets.md) - Built-in alphabets and custom options
|
234
|
+
- [API Reference](api-reference.md) - Complete API documentation
|
235
|
+
- [Use Cases](use-cases.md) - Real-world examples and applications
|
236
|
+
- [Performance](performance.md) - Benchmarks and optimization tips
|
237
|
+
- [Security](security.md) - Security considerations and best practices
|
238
|
+
|
239
|
+
## Troubleshooting
|
240
|
+
|
241
|
+
### Common Issues
|
242
|
+
|
243
|
+
**Migration fails**: Ensure you're using Rails 8.0+ and have the correct database permissions.
|
244
|
+
|
245
|
+
**Generator not found**: Make sure you've added `gem 'opaque_id'` to your Gemfile and run `bundle install`.
|
246
|
+
|
247
|
+
**ID generation fails**: This is extremely rare, but if it happens, check your database constraints and ensure the column allows the configured length.
|
248
|
+
|
249
|
+
### Getting Help
|
250
|
+
|
251
|
+
If you encounter issues:
|
252
|
+
|
253
|
+
1. Check the [API Reference](api-reference.md) for detailed method documentation
|
254
|
+
2. Review the [Usage](usage.md) guide for common patterns
|
255
|
+
3. Check the [Use Cases](use-cases.md) for real-world examples
|
256
|
+
4. Open an issue on [GitHub](https://github.com/nyaggah/opaque_id/issues) with details about your setup and the error
|
data/docs/index.md
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Home
|
4
|
+
nav_order: 1
|
5
|
+
description: "Generate cryptographically secure, collision-free opaque IDs for ActiveRecord models"
|
6
|
+
permalink: /
|
7
|
+
---
|
8
|
+
|
9
|
+
# OpaqueId
|
10
|
+
|
11
|
+
[](https://badge.fury.io/rb/opaque_id)
|
12
|
+
[](https://github.com/rubocop/rubocop)
|
13
|
+
[](https://rubygems.org/gems/opaque_id)
|
14
|
+
|
15
|
+
A Ruby gem for generating cryptographically secure, collision-free opaque IDs for ActiveRecord models. OpaqueId provides a drop-in replacement for `nanoid.rb` using Ruby's built-in `SecureRandom` methods with optimized algorithms for unbiased distribution.
|
16
|
+
|
17
|
+
## Features
|
18
|
+
|
19
|
+
- **๐ Cryptographically Secure**: Uses Ruby's `SecureRandom` for secure ID generation
|
20
|
+
- **โก High Performance**: Optimized algorithms with fast paths for 64-character alphabets
|
21
|
+
- **๐ฏ Collision-Free**: Built-in collision detection with configurable retry attempts
|
22
|
+
- **๐ง Highly Configurable**: Customizable alphabet, length, column name, and validation rules
|
23
|
+
- **๐ Rails Integration**: Seamless ActiveRecord integration with automatic ID generation
|
24
|
+
- **๐ฆ Rails Generator**: One-command setup with `rails generate opaque_id:install`
|
25
|
+
- **๐งช Well Tested**: Comprehensive test suite with statistical uniformity tests
|
26
|
+
- **๐ Rails 8.0+ Compatible**: Built for modern Rails applications
|
27
|
+
|
28
|
+
## Quick Start
|
29
|
+
|
30
|
+
### 1. Add to your Gemfile
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
gem 'opaque_id'
|
34
|
+
```
|
35
|
+
|
36
|
+
### 2. Generate migration and update model
|
37
|
+
|
38
|
+
```bash
|
39
|
+
rails generate opaque_id:install User
|
40
|
+
```
|
41
|
+
|
42
|
+
### 3. Run migration
|
43
|
+
|
44
|
+
```bash
|
45
|
+
rails db:migrate
|
46
|
+
```
|
47
|
+
|
48
|
+
### 4. Use in your models
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
class User < ApplicationRecord
|
52
|
+
include OpaqueId::Model
|
53
|
+
end
|
54
|
+
|
55
|
+
# Create a user - opaque_id is automatically generated
|
56
|
+
user = User.create!(name: "John Doe")
|
57
|
+
puts user.opaque_id # => "V1StGXR8_Z5jdHi6B-myT"
|
58
|
+
|
59
|
+
# Find by opaque_id
|
60
|
+
user = User.find_by_opaque_id("V1StGXR8_Z5jdHi6B-myT")
|
61
|
+
```
|
62
|
+
|
63
|
+
## Why OpaqueId?
|
64
|
+
|
65
|
+
OpaqueId replaces the need for `nanoid.rb` by providing:
|
66
|
+
|
67
|
+
- **Native Ruby implementation** using `SecureRandom`
|
68
|
+
- **Better performance** with optimized algorithms
|
69
|
+
- **Rails 8.0+ compatibility** out of the box
|
70
|
+
- **ActiveRecord integration** with automatic ID generation
|
71
|
+
- **Collision handling** with configurable retry attempts
|
72
|
+
- **Flexible configuration** for different use cases
|
73
|
+
|
74
|
+
## Installation
|
75
|
+
|
76
|
+
### Requirements
|
77
|
+
|
78
|
+
- Ruby 3.2+
|
79
|
+
- Rails 8.0+
|
80
|
+
- ActiveRecord 8.0+
|
81
|
+
|
82
|
+
### Using Bundler (Recommended)
|
83
|
+
|
84
|
+
Add this line to your application's Gemfile:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
gem 'opaque_id'
|
88
|
+
```
|
89
|
+
|
90
|
+
And then execute:
|
91
|
+
|
92
|
+
```bash
|
93
|
+
bundle install
|
94
|
+
```
|
95
|
+
|
96
|
+
### Manual Installation
|
97
|
+
|
98
|
+
```bash
|
99
|
+
gem install opaque_id
|
100
|
+
```
|
101
|
+
|
102
|
+
## Getting Started
|
103
|
+
|
104
|
+
Ready to get started? Check out our [Getting Started Guide](getting-started.md) for a comprehensive walkthrough.
|
105
|
+
|
106
|
+
## Documentation
|
107
|
+
|
108
|
+
- [Getting Started](getting-started.md) - Quick setup and basic usage
|
109
|
+
- [Installation](installation.md) - Detailed installation guide
|
110
|
+
- [Usage](usage.md) - Comprehensive usage examples
|
111
|
+
- [Configuration](configuration.md) - All configuration options
|
112
|
+
- [Alphabets](alphabets.md) - Built-in alphabets and custom options
|
113
|
+
- [Algorithms](algorithms.md) - Technical algorithm details
|
114
|
+
- [Performance](performance.md) - Benchmarks and optimization tips
|
115
|
+
- [Security](security.md) - Security considerations and best practices
|
116
|
+
- [Use Cases](use-cases.md) - Real-world examples and applications
|
117
|
+
- [API Reference](api-reference.md) - Complete API documentation
|
118
|
+
- [Development](development.md) - Contributing and development setup
|
119
|
+
|
120
|
+
## License
|
121
|
+
|
122
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
123
|
+
|
124
|
+
## Contributing
|
125
|
+
|
126
|
+
This project follows an "open source, closed contribution" model. We welcome bug reports, feature requests, and documentation improvements through GitHub Issues.
|
127
|
+
|
128
|
+
## Acknowledgements
|
129
|
+
|
130
|
+
- [nanoid.rb](https://github.com/radeno/nanoid.rb) - Original inspiration and reference implementation
|
131
|
+
- [NanoID](https://github.com/ai/nanoid) - The original JavaScript implementation
|
132
|
+
- [PlanetScale Article](https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api) by Mike Coutermarsh - Excellent explanation of opaque ID benefits
|