{"id":15612476,"url":"https://github.com/kylefox/restable","last_synced_at":"2025-04-28T13:05:35.257Z","repository":{"id":180980973,"uuid":"666018609","full_name":"kylefox/restable","owner":"kylefox","description":"A toolkit for rapidly building REST APIs with Rails.","archived":false,"fork":false,"pushed_at":"2023-09-10T01:49:37.000Z","size":48,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-28T13:04:40.348Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kylefox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-13T14:13:49.000Z","updated_at":"2023-07-17T16:08:43.000Z","dependencies_parsed_at":"2024-10-22T01:25:08.024Z","dependency_job_id":null,"html_url":"https://github.com/kylefox/restable","commit_stats":null,"previous_names":["kylefox/restable"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefox%2Frestable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefox%2Frestable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefox%2Frestable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylefox%2Frestable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kylefox","download_url":"https://codeload.github.com/kylefox/restable/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251319610,"owners_count":21570426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T06:43:11.433Z","updated_at":"2025-04-28T13:05:35.185Z","avatar_url":"https://github.com/kylefox.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Restable\n\nBuilding a REST API — even with Rails — is tedious work. This project aims to eliminate all that tedious work by providing the generic boilerplate functionality that all APIs require so that you can start building out your custom business logic right away. Some aspects of building a REST API in Rails are trivial, in which case guidance on best practices will be provided. Think of Restable as a combination of open-source code and tutorials.\n\nThis project is highly inspired by ideas and concepts found in the [Stripe API](https://stripe.com/docs/api) and [Shopify API](https://shopify.dev/docs/api/admin-rest), and aims to allow you to build APIs of similar quality with as little work as possible.\n\n## Building Blocks\n\nRather that lock you into using a custom DSL or particular architecture, RestEasy will expose opt-in functionality through concerns, helpers, etc. and suggest patterns for organizing your code. Think of RestEasy as a tiny framework for building REST APIs rather than a drop-in, pre-packaged solution.\n\n### Planned Features\n\n- ~Management of **API Secrets** \u0026 generating **secure** token~\n- **Authentication** with basic and bearer token\n- Consistent **error handling**\n- **JSON Serialization** of API resources using JBuilder\n- **Versioning** encouraged through convention over configuration\n\n### Potential Future Features\n\n- **Pagination** with Kaminari\n- **Webhook** delivery to **Endpoints**\n- Generators for quickly scaffolding a new API resource\n- RSpec helpers for testing your API\n- Request logging\n- Expanding responses\n- Request IDs and logging\n- Rate limiting\n- Admin monitoring dashboard\n- Documentation generator\n\n## Usage\n\n### API Credentials\n\nOne of the first things you need to do when developing a REST API is create a model to represent authentication credentials. Rails has an excellent [`has_secure_token`](https://api.rubyonrails.org/classes/ActiveRecord/SecureToken/ClassMethods.html#method-i-has_secure_token) module that handles creation of (surprise!) secure tokens. Restable includes a `Restable::SecureToken` concern that can be included into your model that provides some additional functionality, like presence and uniqueness validation of the `token` attribute.\n\nWe're going to call our credential model `Api::SecretKey`. Let's imagine our app has an `Account` model, and an account can have many secret keys. Let's generate the model:\n\n```bash\nrails generate model api/secret_key token:token account:references\n```\n\n_👉 **Tip:** If you want to use the `Restable::SecureToken` concern, your token column must be named `token`._\n\nThe command above will generate `app/models/api/secret_key.rb` and the associated migration. Rails will add a unique index on `token` to the migration, but it's a good idea to also add a `null: false` constraint to that column:\n\n```diff\ndiff --git create_api_secret_keys.rb create_api_secret_keys.rb\nindex 32c4a68..0b1702e 100644\n--- create_api_secret_keys.rb\n+++ create_api_secret_keys.rb\n@@ -1,11 +1,11 @@\n class CreateApiSecretKeys \u003c ActiveRecord::Migration[7.0]\n   def change\n     create_table :api_secret_keys do |t|\n-      t.string :token\n+      t.string :token, null: false\n       t.references :account, null: false, foreign_key: true\n\n       t.timestamps\n     end\n     add_index :api_secret_keys, :token, unique: true\n   end\n end\n```\n\nThe model file generated by Rails will already include `has_secure_token`. You can remove this and include `Restable::SecureToken` if you like:\n\n```ruby\n# app/models/api/secret_key.rb\nclass Api::SecretKey \u003c ApplicationRecord\n  include Restable::SecureToken\n\n  belongs_to :account\nend\n```\n\nand add the `has_many` to your `Account` model:\n\n```ruby\n# app/models/account.rb\nclass Account \u003c ApplicationRecord\n  has_many :api_secret_keys, dependent: :delete_all, class_name: \"Api::SecretKey\"\nend\n```\n\nRun `db:migrate` and your credential system should be ready to go:\n\n```ruby\naccount = Account.first\nsecret_key = account.api_secret_keys.create!\n# =\u003e \u003cApi::SecretKey:0x00000001077190f0 id: 13, token: \"[FILTERED]\", account_id: 2, created_at: Fri, 14 Jul 2023 16:44:52.462608000 UTC +00:00, updated_at: Fri, 14 Jul 2023 16:44:52.462608000 UTC +00:00\u003e\nsecret_key.token\n# =\u003e \"api_secret_key_yLt4AM6S9RQK9Y1C6kYvJZ8w\"\n```\n\nSometing to notice is the `\"api_secret_key\"` token prefix. `Restable::SecureToken` automatically adds this prefix by singularizing the table name. You can change the prefix by overriding the `secure_token_prefix` class method:\n\n```ruby\nclass Api::SecretKey \u003c ApplicationRecord\n  include Restable::SecureToken\n\n  def self.secure_token_prefix\n    # Generate tokens in the format \"secret_key_yLt4AM6S9RQK9Y1C6kYvJZ8w\"\n    \"secret_key\"\n  end\nend\n```\n\nYou can disable the prefix by having `secure_token_prefix` return `nil`.\n\nOf course, because `Api::SecretKey` is just a normal Rails model, you can add whatever additional functionality you want to it, like an `expires_at` timestamp, a `created_by` attribute to track the user who generated the toke, etc. Or maybe your `Account` model should only have a single secret key, in which case you can specify `has_one :api_secret_key` instead of `has_many :api_secret_keys`.\n\nYou can also create as many credential model types as you need. For example, if you want to dispatch [signed webhooks](https://stripe.com/docs/webhooks/signatures) you could create a `Webhook::Signature` model using the same `Restable::SecureToken` approach.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem \"restable\"\n```\n\nAnd then execute:\n```bash\n$ bundle\n```\n\nOr install it yourself as:\n```bash\n$ gem install restable\n```\n\n## Contributing\n\nContributions are welcome.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylefox%2Frestable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkylefox%2Frestable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylefox%2Frestable/lists"}