{"id":26201873,"url":"https://github.com/sveredyuk/axr","last_synced_at":"2025-04-15T06:01:33.435Z","repository":{"id":65600071,"uuid":"224646912","full_name":"sveredyuk/axr","owner":"sveredyuk","description":"Simple architecture for the better ruby applications","archived":false,"fork":false,"pushed_at":"2021-05-18T10:34:35.000Z","size":855,"stargazers_count":24,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-28T16:43:03.628Z","etag":null,"topics":["architecture","ddd","dsl","ruby"],"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/sveredyuk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-28T12:18:40.000Z","updated_at":"2023-09-16T00:31:44.000Z","dependencies_parsed_at":"2023-01-31T07:45:25.035Z","dependency_job_id":null,"html_url":"https://github.com/sveredyuk/axr","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sveredyuk%2Faxr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sveredyuk%2Faxr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sveredyuk%2Faxr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sveredyuk%2Faxr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sveredyuk","download_url":"https://codeload.github.com/sveredyuk/axr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248714755,"owners_count":21149961,"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":["architecture","ddd","dsl","ruby"],"created_at":"2025-03-12T03:24:09.447Z","updated_at":"2025-04-15T06:01:33.367Z","avatar_url":"https://github.com/sveredyuk.png","language":"Ruby","readme":"# AXR\n\n**Ruby architecture for simplicity and team adoption**\n\nArchitecture's hard. It’s very easy to build a complex system. Much harder to build a simple and adaptable solution. The code doesn't matter. Coding for the sake of writing code is foolish.\n\nOnly a few of us get to write software that survives 5-10 years or longer. 90% of our work is garbage that becomes obsolete in 1-3 years after release. Most of our work hours are wasted on features that will never be useful.\n\nThis is just a reality.\n\n\n(c) Volodya Sveredyuk\n\n## Motivation\nApplication engineering it's always about abstractions and how they describe the real world and business which pays our salaries for coding something that might improve it. Maybe. Sometimes.\n\nI hate doing something alone. I am a team player and as a team player, I prefer conventions over configuration. But this is not working with knowledge responsibility segregation inside the software app. In the Ruby world (especially Rails) it's so easy to add a new feature. Just add one line, one dependency, one callback and now you share knowledge about one entity into another entity. More dependencies - more spaghetti and legacy that in future we should REWRITE EVERYTHING!\n\n\u003cimg src=\"docs/images/rewrite.png\" alt=\"drawing\" width=\"500\"/\u003e\n\nArchitecture's about knowledge responsibility and not the code.\n\nThe worst thing that even we write the architecture document wherein a convenient way to agree on architecture and layers and entities, etc - We are not protected from violation of these conventions.\n\nAnd this the place where AxR comes on the stage.\n\nPlease, welcome the **DSL** that helps:\n1. Describes your application layers (modules)\n2. Defines knowledge responsibilities between them\n3. Checks if you did not violate anything\n\n## Setup\n\nIn your Gemfile\n```ruby\ngem 'axr', group: :development\n```\n\n## DSL\n\nIn your ruby app: (for rails app put it into `config/initializers/axr.rb` file)\n```ruby\nrequire 'axr'\n\nAxR.app.define do\n  layer 'Api'\n  layer 'YourBusinessLogic'\n  layer 'Repo'\nend\n```\n\nBy default, layers will get level from top to bottom.\n```\nApi -\u003e 0\nYourBusinessLogic -\u003e 1\nRepo -\u003e 2\n```\n\nLayers with lower-level have less isolation.\n\n- `Api` knows about `YourBusinessLogic` and `Repo`\n- `YourBusinessLogic` knows about `Repo` but don't know anything about `Api`\n- `Repo` fully isolated and don't familiar with `Api` and `YourBusinessLogic`\n\n**Options**\n\n```ruby\nrequire 'axr'\n\nAxR.app.define do\n  layer 'A'\n  layer 'B', familiar_with: 'C'\n  layer 'C', familiar_with: 'B'\n  layer 'D', isolated: true\n  layer 'E', isolated: true\nend\n```\n\n```ruby\n\n# app.define options\nAxR.app.define(isolated: true) # All layers will be isolated by default\nAxR.app.define(familiar_with: ['D', 'E') # All layers will be familiar with D and E by default\n\n# layer options\nfamiliar_with: [...] # Can operate with other layers\nisolated: true # 100% isolated and should not operate with other layers\nisolated: true, familiar_with: [...] # Isolated from all except familiars\n```\n\nCan organize knowledge structure like:\n\n\u003cimg src=\"docs/images/abcde_example.png\" alt=\"drawing\" width=\"500\"/\u003e\n\n## CLI\n\nRun `AxR` checker in console\n```sh\naxr check . --load path/to/you/app/autoload.rb\n```\n\nFor rails apps\n```sh\naxr check . --load config/environment\n```\n\nRun for a specific directory\n```sh\naxr lib/adapters\n```\n\nRun for a specific file\n```sh\naxr lib/adapters/youtube.rb\n```\n\nFinish scanning with status code 1 in case of any warnings (you can use in CI environment to fail pipeline step)\n```sh\naxr check --exit-on-warnings\n```\n\n## More examples\n\n**ERP system**\n\n\u003cimg src=\"docs/images/erp_example.png\" alt=\"drawing\" width=\"500\"/\u003e\n\n```ruby\nif Rails.env.development? || Rails.env.test?\n  require 'axr'\n\n  AxR.app.define(isolated: true) do\n    layer 'UI',         familiar_with: %w[Docs Inventory Production]\n    layer 'API',        familiar_with: %w[Docs Inventory Production]\n    layer 'Docs',       familiar_with: %w[Inventory Accounts Repo]\n    layer 'Accounts',   familiar_with: %w[Repo]\n    layer 'Inventory',  familiar_with: %w[Repo]\n    layer 'Production', familiar_with: %w[Repo]\n    layer 'Repo'\n  end\nend\n\n```\n\n### TODO\n- Ignore vendor or any other directories dir as configuration\n- Add sublayers\n- Add rubocop cop\n- Add more app examples\n- Migrate to AST analyzer\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsveredyuk%2Faxr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsveredyuk%2Faxr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsveredyuk%2Faxr/lists"}