{"id":20072234,"url":"https://github.com/paulhenri-l/resty","last_synced_at":"2025-10-25T05:17:57.141Z","repository":{"id":57543479,"uuid":"155785106","full_name":"paulhenri-l/resty","owner":"paulhenri-l","description":"Like ActiveResource but for Elixir","archived":false,"fork":false,"pushed_at":"2019-03-28T22:14:22.000Z","size":258,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-09T04:11:14.494Z","etag":null,"topics":["activeresource","client","elixir","rest"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/resty","language":"Elixir","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/paulhenri-l.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-01T22:48:06.000Z","updated_at":"2024-05-19T15:15:14.000Z","dependencies_parsed_at":"2022-08-27T18:50:59.682Z","dependency_job_id":null,"html_url":"https://github.com/paulhenri-l/resty","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulhenri-l%2Fresty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulhenri-l%2Fresty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulhenri-l%2Fresty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulhenri-l%2Fresty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paulhenri-l","download_url":"https://codeload.github.com/paulhenri-l/resty/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252571403,"owners_count":21769828,"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":["activeresource","client","elixir","rest"],"created_at":"2024-11-13T14:39:09.421Z","updated_at":"2025-10-25T05:17:52.107Z","avatar_url":"https://github.com/paulhenri-l.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Resty\n\n[![Build Status](https://travis-ci.org/paulhenri-l/resty.svg?branch=master)](https://travis-ci.org/paulhenri-l/resty)\n[![Code coverage](https://codecov.io/gh/paulhenri-l/resty/branch/master/graph/badge.svg)](https://codecov.io/gh/paulhenri-l/resty)\n\nResty aims to be like [ActiveResource](https://github.com/rails/activeresource)\nbut for Elixir.\n\nActiveResource is great and as I do not intend to reinvent the wheel a lot of\nthe concepts found in ActiveResource have just been ported to this library so\nyou should feel *kinda* right at home.\n\nIf you do not know what ActiverResource is, it is like an ORM but instead of\nusing a database it works with REST APIs.\n\n\u003e Model classes are mapped to remote REST resources by Active Resource much the\n\u003e same way Active Record maps model classes to database tables. When a request\n\u003e is made to a remote resource, a REST JSON request is generated, transmitted,\n\u003e and the result received and serialized into a usable Ruby object.\n\u003e\n\u003e -- \u003ccite\u003eActiveResource README\u003c/cite\u003e\n\n## Installation\n\nFirst, add Resty to your mix.exs dependencies:\n\n```elixir\ndef deps do\n  [{:resty, \"~\u003e 1.0.0\"}]\nend\n```\n\nand run `mix deps.get`.\n\n## Configuration\n\nOut of the box Resty works without needing you to configure anything. But if\nyou want to change the defaults you can do it in your config.exs file.\nConfigurable options can be found in the [documentation](https://hexdocs.pm/resty/Resty.html).\n\n## Usage\n\n### Creating a resource\n\nFirst thing first. In order to use Resty and query an API you'll need a\n**resource**\n\nResources can be created thanks to the `Resty.Resource.Base` module.\n\n```elixir\ndefmodule Post do\n  use Resty.Resource.Base\n\n  # On which site is the resource available? This can also be set globally in\n  # your config.exs file.\n  set_site \"https://jsonplaceholder.typicode.com\"\n\n  # What is the path to the resource?\n  set_resource_path \"/posts\"\n\n  # What attributes exists on the resource?\n  define_attributes [:title, :body, :userId]\nend\n```\n\nAnd now we can do CRUD!\n\n### Find\n\nFind will issue a GET request to the resource.\n\n```elixir\n{:ok, post} = Post |\u003e Resty.Repo.find(1)\n\nIO.inspect(post) # %Post{id: 1, title: \"The title\", body: \"The body\", userId: 1}\n```\n\n#### Under the hood\n\n```\n# Request -\u003e GET https://jsonplaceholder.typicode.com/posts/1\n# Response -\u003e {\"id\": 1, \"title\": \"The title\", \"body\": \"The body\", \"userId\": 1}\n```\n\n### Create\n\nCreate will issue a POST request to the resource\n\n```elixir\n{:ok, post} = Post.build(title: \"The title\", body: \"The body\", userId: 1) |\u003e Resty.Repo.save()\n\nIO.inspect(post) # %Post{id: 1, title: \"The title\", body: \"The body\", userId: 1}\n```\n\n#### Under the hood\n\n```\n# Request -\u003e POST https://jsonplaceholder.typicode.com/posts\n# Request Body -\u003e {\"title\": \"The title\", \"body\": \"The body\", \"userId\": 1}\n# Response -\u003e {\"id\": 2, \"title\": \"The title\", \"body\": \"The body\", \"userId\": 1}\n```\n\n### Update\n\nUpdate will issue a PUT request to the resource\n\n```elixir\n{:ok, post} = Post |\u003e Resty.Repo.find(1)\n\n{:ok, updated_post} = %{post | title: \"updated-title\"} |\u003e Resty.Repo.save()\n\nIO.inspect(update_post) # %Post{id: 1, title: \"updated-title\", body: \"The body\", userId: 1}\n```\n\n#### Under the hood\n\n```\n# Request -\u003e PUT https://jsonplaceholder.typicode.com/posts/1\n# Request Body -\u003e {\"title\": \"updated-title\", \"body\": \"The body\", \"userId\": 1}\n# Response -\u003e {\"id\": 1, \"title\": \"updated-title\", \"body\": \"The body\", \"userId\": 1}\n```\n\n### Delete\n\nDelete will issue a DELETE request to the resource\n\n```elixir\n{:ok, post} = Post |\u003e Resty.Repo.find(1)\n{:ok, true} = post |\u003e Resty.Repo.delete()\n```\n\n#### Under the hood\n\n```\n# Request -\u003e DELETE https://jsonplaceholder.typicode.com/posts/1\n# Response -\u003e 204 No Content\n```\n\n### Associations\n\nHere are the associations that are supported by resty. Do note that associations\nwon't be automaticaly saved. If you change their values you'll have to manually\nsave them.\n\n#### BelongTo\n\nResty is able to automaticaly resolve your belongs to associations.\n\n```elixir\ndefmodule User do\n  use Resty.Resource.Base\n\n  set_site \"https://jsonplaceholder.typicode.com\"\n  set_resource_path \"/users\"\n  define_attributes [:name, :email]\nend\n\ndefmodule Post do\n  use Resty.Resource.Base\n\n  set_site \"https://jsonplaceholder.typicode.com\"\n  set_resource_path \"/posts\"\n  define_attributes [:title, :body, :userId]\n\n  belongs_to User, :user, :userId\nend\n\n{:ok, post} = Post |\u003e Resty.Repo.find(1)\n\nIO.inspect(post.user) # %User{id: 1, email: \"Sincere@april.biz\", name: \"Leanne Graham\"}\n```\n\nUnder the hood\n\n```\n# Request -\u003e GET https://jsonplaceholder.typicode.com/posts/1\n# Request -\u003e GET https://jsonplaceholder.typicode.com/users/1\n# Response -\u003e {\"id\": 1, \"title\": \"The title\", \"body\": \"The body\", \"userId\": 1}\n# Response -\u003e {\"id\": 1, \"email\": \"Sincere@april.biz\", \"name\": \"Leanne Graham\"}\n```\n\n#### HasOne\n\nResty is able to automaticaly resolve your has one associations.\n\n*If the association is already in the response body it won't get refetched*\n\n```elixir\ndefmodule Company do\n  use Resty.Resource.Base\n\n  set_site \"https://jsonplaceholder.typicode.com\"\n  set_resource_path \"/users/:user_id/company\"\n  define_attributes [:name]\nend\n\ndefmodule User do\n  use Resty.Resource.Base\n\n  set_site \"https://jsonplaceholder.typicode.com\"\n  set_resource_path \"/users\"\n  define_attributes [:name, :email]\n\n  has_one Company, :company, :userId\nend\n\n{:ok, user} = User |\u003e Resty.Repo.find(1)\n\nIO.inspect(user.company.name) # Romaguera-Crona\n```\n\nUnder the hood\n\n```\n# Request -\u003e GET https://jsonplaceholder.typicode.com/users/1\n# Request -\u003e GET https://jsonplaceholder.typicode.com/users/1/company\n# Response -\u003e {\"id\": 1, \"email\": \"Sincere@april.biz\", \"name\": \"Leanne Graham\"}\n# Response -\u003e {\"name\": \"Romaguera-Crona\"}\n```\n\n#### HasMany\n\nResty is able to automaticaly resolve your has many associations.\n\n*If the association is already in the response body it won't get refetched*\n\n```elixir\ndefmodule Comment do\n  use Resty.Resource.Base\n\n  set_site \"https://jsonplaceholder.typicode.com\"\n  set_resource_path \"/posts/:post_id/comments\"\n  define_attributes [:postId, :body]\nend\n\ndefmodule Post do\n  use Resty.Resource.Base\n\n  set_site \"https://jsonplaceholder.typicode.com\"\n  set_resource_path \"/posts\"\n  define_attributes [:title, :body]\n\n  has_many Comment, :comments, :postId\nend\n\n{:ok, post} = Post |\u003e Resty.Repo.find(1)\n\nIO.inspect(user.post.comments) # [%Comment{name: \"id labore ex et quam laborum\"\"} | _]\n```\n\nUnder the hood\n\n```\n# Request -\u003e GET https://jsonplaceholder.typicode.com/posts/1\n# Request -\u003e GET https://jsonplaceholder.typicode.com/posts/1/comments\n# Response -\u003e {\"userId\": 1, \"id\": 1, \"title\": \"...\", \"body\": \"...\"}\n# Response -\u003e [{\"postId\": 1, \"id\": 1, \"name\": \"...\", \"email\": \"...\", \"body\": \"...\"}, {...}]\n```\n\n### Authentication\n\nSome API will require you to authenticate your requests. Out of the box Resty\nsupport *Basic* and *Bearer* auth.\n\n#### Basic\n\nMore informations about this auth strategy can be found [here](https://hexdocs.pm/resty/Resty.Auth.Basic.html)\n\n```elixir\ndefmodule Post do\n  use Resty.Resource.Base\n\n  set_site \"https://jsonplaceholder.typicode.com\"\n  set_resource_path \"/posts\"\n  define_attributes [:title, :body, :userId]\n  with_auth Resty.Auth.Basic, user: \"hello\", password: \"hola\"\nend\n```\n\n#### Bearer token\n\nMore informations about this auth strategy can be found [here](https://hexdocs.pm/resty/Resty.Auth.Bearer.html)\n\n```elixir\ndefmodule Post do\n  use Resty.Resource.Base\n\n  set_site \"https://jsonplaceholder.typicode.com\"\n  set_resource_path \"/posts\"\n  define_attributes [:title, :body, :userId]\n  with_auth Resty.Auth.Beaer, token: \"my-token\"\nend\n```\n\n## Docs\n\nThe documentation is available here [https://hexdocs.pm/resty](https://hexdocs.pm/resty)\n\nThe most important modules are `Resty.Repo`, `Resty.Resource.Base` and `Resty.Resource`.\n\n## Contributing\n\nIf you have any questions about how to use this library feel free to open\nan issue :)\n\nIf you think that the documentation or the code could be improved open a PR\nand I'll happily review it!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulhenri-l%2Fresty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulhenri-l%2Fresty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulhenri-l%2Fresty/lists"}