{"id":19335022,"url":"https://github.com/matt-taylor/json_schematize","last_synced_at":"2025-09-08T00:09:58.429Z","repository":{"id":40452404,"uuid":"467670030","full_name":"matt-taylor/json_schematize","owner":"matt-taylor","description":"Turn JSON data into nested Schema Ruby Objects. Remove unimportant data and keep what you need","archived":false,"fork":false,"pushed_at":"2025-05-22T01:30:12.000Z","size":64,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-27T14:02:03.901Z","etag":null,"topics":["cache-layer","json","ruby","schema"],"latest_commit_sha":null,"homepage":"","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/matt-taylor.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-08T20:45:27.000Z","updated_at":"2025-05-22T01:28:49.000Z","dependencies_parsed_at":"2024-06-16T05:41:44.551Z","dependency_job_id":"3318c79f-57a6-4c36-9a7f-90e1ba9e0754","html_url":"https://github.com/matt-taylor/json_schematize","commit_stats":{"total_commits":16,"total_committers":2,"mean_commits":8.0,"dds":0.0625,"last_synced_commit":"3ba75f1118a42d36b9bc071a7c70a303a3466e6c"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/matt-taylor/json_schematize","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-taylor%2Fjson_schematize","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-taylor%2Fjson_schematize/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-taylor%2Fjson_schematize/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-taylor%2Fjson_schematize/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matt-taylor","download_url":"https://codeload.github.com/matt-taylor/json_schematize/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-taylor%2Fjson_schematize/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274113119,"owners_count":25224348,"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","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cache-layer","json","ruby","schema"],"created_at":"2024-11-10T03:04:31.307Z","updated_at":"2025-09-08T00:09:58.407Z","avatar_url":"https://github.com/matt-taylor.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JsonSchematize\n\n`JsonSchematize` is emant to be a simple schema control version used to aprse data returned from any API.\n\nIt can handle nested Schematized versions and build the tree all the way down\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'json_schematize'\n```\n\nAnd then execute:\n\n    $ bundle install\n\nOr install it yourself as:\n\n    $ gem install json_schematize\n\n## Usage\n\nGiven hash value of the following:\n```json\n{\n  \"status\":\"complete\",\n  \"id\":\"127392\",\n  \"body\":\n    [\n      {\n        \"status\":\"failed\",\n        \"id\":\"12345\",\n        \"field_i_dont_care_about\": false\n      },\n      {\n        \"status\":\"failed\",\n        \"id\":\"6347\",\n        \"field_i_dont_care_about\": true\n      }\n    ]\n}\n```\n\n```ruby\n# lib/schema/internal_body\nrequire 'json_schematize/generator'\n\nclass InternalBody \u003c JsonSchematize::Generator\n  ALLOWED_STATUSES = [:failed, :completed, :success]\n\n  add_field name: :id, type: Integer\n  add_field name: :status, type: Symbol, validator: -\u003e(transformed_value, raw_value) { ALLOWED_STATUSES.include?(transformed_value) }\nend\n\n###\n# lib/schema/my_first_schema\nrequire 'json_schematize/generator'\nrequire 'internal_body' #dependeing on load order\n\nclass MyFirstSchema \u003c JsonSchematize::Generator\n  add_field name: :internals, type: InternalBody, array_of_types: true, dig: [\"body\"]\n  add_field name: :id, type: Integer\n  add_field name: :status, type: Symbol\nend\n\nschema = MyFirstSchema.new(**json_hash)\nschema.internals.count #=\u003e 2\nschema.internals.first.status #=\u003e :failed\nschema.id #=\u003e 127392\nschema.id = 999999  #assignments are still subject to validation logic for each field\nschema.id #=\u003e 999999\n```\n\n### Field options:\n```\nname -- Name of the field. Field name can be accessed from the instance\ntype -- Class of the expected field type\ntypes -- To be used when you want the field to have multiple types. Useful for similar classes like DateTime, Date, Time (converter must be supplied when multiple types are given)\ndig_type -- Methodolgy of how to dig into the given param for the field. All values of the `dig` array will be converted accordingly. Default is `none` and will attempt to use what is given. [:symbol, :string, :none].\ndig -- Array telling JsonSchematize how to dig into the provided hash\nvalidator -- Proc value to validate the data found in the params. Proc given (transformed_value, original_value) when calling in\nrequired -- Default is true. When not set, each instance class can optionally decide if they want to raise when an this is set to false.\nconverter -- Proc return is set to the field value. No furter validation is done. Given (value) as a parameter\narray_of_types -- Detailed example above. Set this value to true when the dig param is to an array and you want all values in array to be parsed the given type\nempty_value -- When required is false, this value is used to fill the field. By default it is JsonSchematize::EmptyValue, but can be changed to anything\n```\n\n### Schema defaults\n\nDefaults can be added for all fields for any of the available options. This can be useful for returned API calls when the body is parsed as a Hash with String keys.\n\n```ruby\nclass SchemaWithDefaults \u003c JsonSchematize::Generator\n  schema_default option: :dig_type, value: :string\n\n  add_field name: :internals, type: InternalBody, array_of_types: true\n  add_field name: :id, type: Integer\n  add_field name: :status, type: Symbol, required: false, empty_value: \"empty\"\nend\n```\n\n### Custom Classes\n\n```ruby\nclass CustomClasses \u003c JsonSchematize::Generator\n  # JsonSchematize::Boolean can be used as a type when expecting a conversion of possible true or false values converted into a TrueClass or FalseClass\n  add_field name: :internals, type: JsonSchematize::Boolean\nend\n```\n\n### Caching Adapter\n\nJsonSchematize is built to be schema for API results. But what happens when you dont expect the result to change? Introducing the caching layer. This layer lets you cache a `JsonSchematize` object that can be queried from later\n\n**Note: This requires redis**\n\n```ruby\nclass CachedClass \u003c JsonSchematize::Generator\n  include JsonSchematize::Cache\n  cache_options key: -\u003e(instance_of_cached_class, cache_key_from_initialization) { \"#{instance_of_cached_class.id}:#{cache_key_from_initialization}\" }\n  cache_options ttl: 7.days.to_i\n\n  schema_default option: :dig_type, value: :string\n\n  add_field name: :id, type: Integer\nend\n\nparams = { id: 1 }\nCachedClass.new(cache_key: User.first.id, **params)\n###\nparams = { \"id\" =\u003e 1 }\nCachedClass.new(params, cache_key: User.first.id)\n```\n\n#### Instance methods for Cache\n```ruby\n# optional cache_key added on initialization: Can be used to customize the cache entry for the instance\nitem = CachedClass.new(cache_key: User.first.id, **params)\n\n# Update the cached item -- Note: This will overwrite the previous cached item IFF the `__cache_key__` remains the same. This is not gaurenteed\n# Optional Param: with_delete, Default true -- Will attempt to delete the original object\nitem.__update_cache_item__\n\n# Manually delete the cached entry\nitem.__clear_entry__!\n\n# Cache key for the item\nitem.__cache_key__\n```\n\n#### Class methods for Cache\n```ruby\n# Retrieve all cached items for the class. Returns an array of CachedClass objects. Only objects that have not expired via TTL\n# Optional: key_includes: \"string_expected_in_cache\", default is nil and return everthing\nCachedClass.cached_items\n\n# Retrieves all valid object keys from the cache\nCachedClass.cached_keys\n\n# Clears all cached items for the given class\nCachedClass.clear_cache!\n\n# manually clear objects that have expired\nCachedClass.clear_unscored_items!\n```\n### Cache options\n```ruby\n# [Required] false; [Expect] Proc; [Return] String to be used as instance key; [Default] key will be the hash of the object\ncache_options key: -\u003e(instance_of_class, custom_key) { }\n\n# [Required] false; [Expect] String; [Default] ENV[\"CACHE_LAYER_REDIS_URL\"] || ENV[\"REDIS_URL\"]\ncache_options redis_url: _redis_url_value\n\n# [Required] false; [Expect] Redis Object or Proc that returns value of Redis Client; [Default] Redis.new(url: redis_url)\ncache_options redis_client: redis_client\n\n# [Required] false; [Expect] Object that plays with to_s and has no spaces; [Default] Full class name downcased\ncache_options cache_namespace: cache_namespace\n\n# [Required] false; [Expect] Integer in seconds; [Default] 1 day\ncache_options ttl: (60 * 60)\n\n# [Required] false; [Expect] Boolean; [Default] true\n# Update the cache when a value has been changed manually\ncache_options update_on_change: true\n\n# [Required] false; [Expect] Float; [Default] 0.8\n# Expected value to be between 0 and 1. The sample rate that the class will clear oldcache values on retreival\ncache_options stochastic_cache_bust: 0.8\n```\n\n## Development\n\nThis gem can be developed against local machine or while using docker. Simpleified Docker commands can be found in the `Makefile` or execute `make help`\n\n## Contributing\n\nThis gem welcomes contribution.\n\nBug reports and pull requests are welcome on GitHub at\nhttps://github.com/matt-taylor/json_schematize.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatt-taylor%2Fjson_schematize","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatt-taylor%2Fjson_schematize","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatt-taylor%2Fjson_schematize/lists"}