{"id":28578147,"url":"https://github.com/digitalocean/kartograph","last_synced_at":"2025-06-11T01:08:57.829Z","repository":{"id":19373609,"uuid":"22613975","full_name":"digitalocean/kartograph","owner":"digitalocean","description":"Kartograph makes it easy to generate and convert JSON. It's intention is to be used for API clients.","archived":false,"fork":false,"pushed_at":"2023-07-06T20:00:35.000Z","size":232,"stargazers_count":153,"open_issues_count":6,"forks_count":38,"subscribers_count":161,"default_branch":"main","last_synced_at":"2025-05-23T19:47:27.728Z","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/digitalocean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2014-08-04T17:51:29.000Z","updated_at":"2025-05-13T04:13:36.000Z","dependencies_parsed_at":"2024-06-18T14:00:23.735Z","dependency_job_id":"bdf76e35-a2d4-41b4-b5f8-f6fa6bf4f9d3","html_url":"https://github.com/digitalocean/kartograph","commit_stats":{"total_commits":85,"total_committers":9,"mean_commits":9.444444444444445,"dds":"0.42352941176470593","last_synced_commit":"6a81185e3785c132ef61e67154ac81940fbb1382"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fkartograph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fkartograph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fkartograph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fkartograph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalocean","download_url":"https://codeload.github.com/digitalocean/kartograph/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fkartograph/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259178491,"owners_count":22817387,"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":"2025-06-11T01:08:57.000Z","updated_at":"2025-06-11T01:08:57.806Z","avatar_url":"https://github.com/digitalocean.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kartograph\n\nA Serialization / Deserialization library.\n\n[![Build Status](https://travis-ci.org/digitalocean/kartograph.svg?branch=master)](https://travis-ci.org/digitalocean/kartograph)\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'kartograph'\n\nAnd then execute:\n\n    $ bundle\n\n## Usage\n\nKartograph makes it easy to generate and convert JSON. It's intention is to be used for API clients.\n\nFor example, if you have an object that you would like to convert to JSON for a create request to an API. You would have something similar to this:\n\n```ruby\nclass UserMapping\n  include Kartograph::DSL\n\n  kartograph do\n    mapping User # The object we're mapping\n\n    property :name, :email, scopes: [:create, :update]\n    property :id, scopes: :read\n  end\nend\n\nuser = User.new(name: 'Bobby Tables')\njson_for_create = UserMapping.representation_for(:create, user)\n```\n\n### Rendering Objects or Collections as Hashes\n\n```ruby\nuser = User.new(name: 'PB Jelly')\nusers = [user]\n\nhash = UserMapping.hash_for(:read, user)\nhash_collection = UserMapping.hash_collection_for(:read, user)\n```\n\n### Rendering Collections as JSON\n\n```ruby\nuser = User.new(name: 'Bobby Tables')\nusers = Array.new(10, user)\n\njson = UserMapping.represent_collection_for(:read, users)\n```\n\n---\n\nSome API's will give you the created resource back as JSON as well on a successful create. For that, you may do something like this:\n\n```ruby\nresponse = HTTPClient.post(\"http://something.com/api/users\", body: json_for_create)\ncreated_user = UserMapping.extract_single(response.body, :read)\n```\n\nMost API's will have a way of retrieving an entire resource collection. For this you can instruct Kartograph to convert a collection.\n\n```ruby\nresponse = HTTPClient.get(\"http://something.com/api/users\")\nusers = UserMapping.extract_collection(response.body, :read)\n# =\u003e [ User, User, User ]\n```\n\n### Getting Harder\n\nSometimes resources will nest other properties under a key. Kartograph can handle this as well.\n\n```ruby\nclass UserMapping\n  include Kartograph::DSL\n\n  kartograph do\n    mapping User # The object we're mapping\n\n    property :name, scopes: [:read]\n\n    property :comments do\n      mapping Comment # The nested object we're mapping\n\n      property :text, scopes: [:read]\n      property :author, scopes: [:read]\n    end\n  end\nend\n```\n\nJust like the previous examples, when you serialize this. It will include the comment block for the scope defined.\n\n### Root Keys\n\nKartograph can also handle the event of root keys in response bodies. For example, if you receive a response with:\n\n```json\n{ \"user\": { \"id\": 123 } }\n```\n\nYou could define a mapping like this:\n\n\n```ruby\nclass UserMapping\n  include Kartograph::DSL\n\n  kartograph do\n    mapping User\n    root_key singular: 'user', plural: 'users', scopes: [:read]\n    property :id, scopes: [:read]\n  end\nend\n```\n\nThis means that when you call the same thing:\n\n```ruby\nresponse = HTTPClient.get(\"http://something.com/api/users\")\nusers = UserMapping.extract_collection(response.body, :read)\n```\n\nIt will look for the root key before trying to deserialize the JSON response.\nThe advantage of this is it will only use the root key if there is a scope defined for it.\n\n\n### Including other definitions within eachother\n\nSometimes you might have models that are nested within eachother on responses. Or you simply want to cleanup definitions by separating concerns. Kartograph lets you do this with includes.\n\n```ruby\nclass UserMapping\n  include Kartograph::DSL\n\n  kartograph do\n    mapping User\n    property :id, scopes: [:read]\n    property :comments, plural: true, include: CommentMapping\n  end\nend\n\nclass CommentMapping\n  include Kartograph::DSL\n\n  kartograph do\n    mapping Comment\n    property :id, scopes: [:read]\n    property :text, scopes: [:read]\n  end\nend\n```\n\n\n### Scope blocks\n\nSometimes adding scopes to all properties can be tedious, to avoid that, you can define properties within a scope block.\n\n```ruby\nclass UserMapping\n  include Kartograph::DSL\n\n  kartograph do\n    scoped :read do\n      property :name\n      property :id\n      property :email, key: 'email_address' # The JSON returned has the key of email_address, our property is called email however.\n    end\n\n    scoped :update, :create do\n      property :name\n      property :email, key: 'email_address'\n    end\n  end\nend\n```\n\nNow when JSON includes comments for a user, it will know how to map the comments using the provided Kartograph definition.\n\n---\n\n### Caching\n\nKartograph has the option to cache certain serializations, determined by the way you setup the key.\n\n```ruby\nclass UserMapping\n  include Kartograph::DSL\n\n  kartograph do\n    cache { Rails.cache } # As long as this respond to #fetch(key_name, options = {}, \u0026block) it will work\n    cache_key { |object| object.cache_key }\n\n    end\n  end\nend\n```\n\n## Contributing\n\n1. Fork it ( https://github.com/digitaloceancloud/kartograph/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fkartograph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalocean%2Fkartograph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fkartograph/lists"}