# API Routes ![API Routes](https://raw.githubusercontent.com/PageRentS/rents-sdk-ruby/master/modeling/API%20Routes.png) # Simple workflow overview 1. Every class which consumes API must have the `Connection` class as parent 2. `Connection` implement the HTTP RestClient methods 3. Every message between the Developer app & the RentS framework must be a HashMap/Dictionary 4. The object attrs are dynamic, based on the Hash received as constructor param 5. Instantiation example ```ruby @transaction = Rents::Transaction.new({ card:{ brand: 'visa', cvv: '123', expiration_month: '05', expiration_year: '2018', number: '4012001037141112', holder: Faker::Name.name, }, recurrence_period_id: Rents.enum[:recurrence_periods][:daily], amount: amount }) # Charge @resp = @transaction.charge_store # same as @transaction.charge_store @transaction.resp ``` 6. The `charge_store` implementation: ```ruby def charge_store full_resp=false # method which setup this attrs to HTTP param, like sold_items array to GET params custom_http_params # dynamic path (the conection just read it path to send the HTTP request, so it is a config before perform) self.path = 'transactions/store' # full_resp = need the full HTTP Response (with code, headers...) # if not full_resp return just Hash/Dictionary resp full_resp ? self.resp = self.post_request : self.resp = self.post_json_request # return it received resp self.resp end ``` 7. It `Connection.new.post_request` implementation: ```ruby def post_request # URL configured on the Connection child class method & the params received from the constructor RestClient.post self.url_requested, self.request_params end ``` 8. It `Connection.new.post_json` implementation ```ruby resp = RestClient.post(self.url_requested, self.request_params) to_hash_with_symbols(resp) # Used on all the _json requests def to_hash_with_symbols json JSON.parse(json).it_keys_to_sym end ``` # What the user (developer) see 1. A file which the developer config his environment: ```ruby # The RentS give to you 2 diferent apps, the production & the ratification (homolog) app if developement_env || test_env # Example using direct declaration (bad way, but must be possible) Rents.app_id = 'YOUR_APP_ID' Rents.secret_key = 'YOUR_APP_SECRET_KEY' # TODO: Uncomment test_env if you want to test using RentS default_global app # Rents.test_env = true # TODO: Uncomment debugger if you have an RentS instance on your machine # Rents.debug = true else # Production app # Example using the secret config file # REMEMBER to tell the client to not versioned those config files, like the SECRETs on the RAILS # Extensions config files: # (Ruby => .YML, PHP => .INI, JavaScript => JSON, ObjectiveC => .PLIST, C# => .DLL, Java => .XML) Rents.app_id = Rails.application.secrets.rents['app_id'] Rents.secret_key = Rails.application.secrets.rents['app_id'] ``` 2. The Secret YML example ```yml production: rents: app_id: # TODO copy it from your PRODUCTION APP RentS page app_secret_key: # TODO copy it from your PRODUCTION APP RentS page ``` 3. ENUMs You can add ENUMs file or just get it from the API, but to improve the performance, create those files: * Those [__files__](https://github.com/PageRentS/rents-sdk-ruby/tree/master/lib/rents/config/enums) are not visible to the Developer, but he can check if & easy access through a `Rents.enums` * __`brands.yml`__ ```yml brands: # SampleObj - id: 0 name: Nil username: nil # VISA - id: 1 name: VISA username: visa ``` * __`currencies.yml`__ ```yml currencies: - id: 0 name: Nil acronym: nil$ iso_code: NIL iso_number: 000 # Real - id: 1 name: Real acronym: R$ iso_code: BRL iso_number: 986 ``` * __`proxy.yml`__ ```yml login: c1280361 password: 12345678 host: proxy.oranization.com port: 80 ``` # How this work in the core 1. The Rents is a Module/Namespace which have static methods (config), like: * `bolean test_env` * `bolean debug` * `enum` (return a HashMap based on the config files: .ini, .yml, .xml, .plist...) * `load_config_file` (return it file to the enum method: `load_yml`, `load_xml`, `load_ini`....) * `proxy` (setup the proxy to the requests, useful for intranets & server apps in shared servers) 2. `Connection.rb`, parent class for all API consumer classes, RestClient (GET, POST, PUT, DELETE) * It must have both methods: `http_method_json` & `http_method`, `setup_default_app` * `setup_default_app`: setup a `Rents.app_id` & `Rents.secret_key` & `this.recurrent_rid` * `setup_default_app` also setup the auth: `this.auth = {app_id:Rents.app_id, secret_key:Rents.secret_key}` * using actions: `this.path = 'global_app'` & `this.path = 'global_subscription'` ```ruby # SetUp a default app if Rents.test_env == true def setup_default_app # setup test_app path self.path = 'global_app' # Get the App & setup config app = get_json_request[:app] Rents.app_id = app[:id] Rents.secret_key = app[:secret] # Get the GlobalRecurrent & setup/config self.path = 'global_subscription' recurrence = get_json_request self.recurrent_rid = recurrence[:rid] return puts 'Please run: rails g rents:install' if Rents.app_id.nil? || Rents.secret_key.nil? self.auth = {app_id:Rents.app_id, secret_key:Rents.secret_key} self.request_params.merge!(auth:self.auth) end ``` * `http_method_json`: return a simple HashMap * `http_method`: return the complet request resp, with code (200, 404, 403...) * `setup_attrs(params)` params = constructor_params, it method iterate the hash attrs & set it as obj attr ```ruby # Dynamic attributtes params.each do |key, value| next unless key.to_s.index('[]').nil? self.class.__send__(:attr_accessor, :"#{key}") self.__send__("#{key}=", value) end ``` * Methods: `this.get_json`, `this.post_json`, `this.get`, `this.post` * Attributtes (the first option is __`test_env`__ the second is production): ```ruby attr_accessor :auth = {app_id: '', app_secret: ''} attr_accessor :path = '' attr_accessor :domain = 'localhost:7000' || 'apprents.herokuapp.com' attr_accessor :protocol = 'http' || 'https' attr_accessor :end_point = this.protocol + "://" + this.domain + "api" attr_accessor :api_version = 'v1' attr_accessor :recurrent_rid = Rents.global_recurrence || rents_id,remote_id (rid) attr_accessor :request_params = hash_received_on_constructor attr_accessor :end_point_versioned = this.protocol + "://" + this.domain + "api" + this.api_version ```