{"id":13509085,"url":"https://github.com/meh/urna","last_synced_at":"2025-08-21T05:32:52.971Z","repository":{"id":9273325,"uuid":"11103275","full_name":"meh/urna","owner":"meh","description":"REST in peace.","archived":false,"fork":false,"pushed_at":"2017-05-16T02:24:33.000Z","size":59,"stargazers_count":94,"open_issues_count":1,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-08-14T22:39:48.589Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-07-01T18:25:42.000Z","updated_at":"2025-06-10T22:15:22.000Z","dependencies_parsed_at":"2022-09-01T03:51:29.219Z","dependency_job_id":null,"html_url":"https://github.com/meh/urna","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/meh/urna","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Furna","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Furna/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Furna/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Furna/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meh","download_url":"https://codeload.github.com/meh/urna/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Furna/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271430850,"owners_count":24758399,"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-08-21T02:00:08.990Z","response_time":74,"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":[],"created_at":"2024-08-01T02:01:02.756Z","updated_at":"2025-08-21T05:32:52.660Z","avatar_url":"https://github.com/meh.png","language":"Elixir","funding_links":[],"categories":["REST and API"],"sub_categories":[],"readme":"Urna - REST in peace\n====================\n*Urna* is a simple DSL around [cauldron](https://github.com/meh/cauldron) to\nimplement REST services.\n\nBasics\n------\n*Urna* tries to follow the REST style as closely as possible, there are\nnamespaces and resources, and standard requests to these resources will receive\nproper answers.\n\nIt includes `OPTIONS` requests being properly processed, requests on non-existent\nresources being answered with `404` and verbs not implemented for the resource being\nanswered with a `405`.\n\n```elixir\ndefmodule Example do\n  use Urna\n\n  # namespace is used to define an additional path to access the resource, in\n  # this case /foo/.\n  namespace :foo do\n    # resource is used to, you guessed it, define a resource, since we're in\n    # the :foo namespace it will be accessible at /foo/bar.\n    resource :bar do\n      # A get without a parameter responds to a GET request to the resource, in\n      # this case /foo/bar.\n      #\n      # The result of the block is automatically converted to an accepted\n      # content type extracted from the Accept header.\n      get do\n        42\n      end\n\n      # A get with a parameter responds to a GET request to the resource with\n      # an additional value, in this case /foo/bar/:id.\n      get id do\n        id\n      end\n\n      # A post without a parameter, alike get, responds to a POST request to\n      # the resource, again in this case /foo/bar.\n      #\n      # You can access the decoded content in the params variable, the decoding\n      # is done based on the Content-Type header assumed there's an available\n      # decoder for that type.\n      post do\n        param(\"id\")\n      end\n\n      # Other common verbs are available: head, get, post, put, delete.\n      #\n      # If you want you can define your own verbs too, instead of using the\n      # available ones you can use the verb function.\n      #\n      # In this case it will respond to a HUE request on /foo/bar.\n      verb \"HUE\" do\n        \"huehuehuehue\"\n      end\n    end\n  end\nend\n```\n\nReplying to or failing the request\n----------------------------------\nSometimes you want to answer with a failure or a success with a specific\nresponse code and text.\n\nTo do this you can use the `reply` and `fail` functions. Both functions take as\nfirst parameter the error code, unless a text parameter is given it will use\nthe standard text.\n\nIf a result is also given, it's expected as first parameter.\n\n```elixir\ndefmodule Example do\n  use Urna\n\n  resource :foo do\n    # I'm a tea pot.\n    get do\n      fail 418\n    end\n  end\n\n  resource :bar do\n    # Here you could do something with the parameters and write a row to a\n    # table, so you'd want to answer to the request with a 201 (Created)\n    # response, on top with the newly created row.\n    post do\n      Hey.create(params()) |\u003e reply 201\n    end\n  end\nend\n```\n\nVerb parameter conversion\n-------------------------\n*Urna* also supports converting the verb parameter to an `integer` or `float`,\nfor more complex conversion you'll have to deal it yourself.\n\n```elixir\ndefmodule Example do\n  use Urna\n\n  resource :baz do\n    get id, as: Integer do\n\n    end\n  end\nend\n```\n\nAccessing various variables\n---------------------------\nOn top of `params` there are other useful variables you can access.\n\n* `headers` contains the headers of the request.\n* `uri` is the `URI.Info` of the request.\n* `query` is the decoded query part of the uri.\n\nAdapters\n--------\n*Urna* supports various adapters and it's easy to extend them as well.\n\nAdapters are used to deal with encoding and decoding based on the value of\n`Accept` and `Content-Type` headers.\n\nThe ones provided out of the box are an `application/json` adapter based on\n[jazz](https://github.com/meh/jazz) and an `application/x-www-form-urlencoded`\nadapter which uses the standard `URI.decode_query` function.\n\n```elixir\ndefmodule Example do\n  use Urna, adapters: [Urna.JSON, Urna.Form]\n\n  resource :foo do\n    get do\n      [foo: :bar]\n    end\n  end\nend\n```\n\nCORS\n----\n*Urna* supports CORS out of the box, just pass what to allow on `use Urna` and\nit will handle the various access control headers automatically.\n\n```elixir\ndefmodule API do\n  use Urna, allow: [methods: true, headers: true, credentials: true]\nend\n```\n\nThis example will allow all methods, headers and HTTP credentials, check the\ndocumentation for more information.\n\n\nDeploying on Heroku\n-------------------\n\nGive an app (mix is required):\n\n```elixir\ndefmodule TestApp do\n  use Urna\n\n  resource \"\", do: \"hello world!\"\nend\n```\n\n\nCreate an app with the elixir buildpack:\n\n    heroku create --buildpack https://github.com/HashNuke/heroku-buildpack-elixir.git\n\n\nAdd a `Procfile` with the following line:\n\n    web: mix run -e \"{:ok,_} = Urna.start TestApp, port: ${PORT:-3000}\" --no-halt\n\n\nPush the app to deploy it:\n\n    git push heroku master\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeh%2Furna","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeh%2Furna","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeh%2Furna/lists"}