├── rails7 └── pt-br │ ├── img │ ├── logo.png │ ├── cover.png │ ├── pow_running.png │ └── old-logo.svg │ ├── api_on_rails.adoc │ └── chapter00-before.adoc ├── rails6 ├── pt-br │ ├── img │ │ ├── cover.png │ │ ├── pow_running.png │ │ └── logo.svg │ ├── api_on_rails.adoc │ └── chapter00-before.adoc ├── en │ ├── img │ │ ├── pow_running.png │ │ └── logo.svg │ ├── api_on_rails.adoc │ ├── chapter00-before.adoc │ └── chapter02-api.adoc ├── es │ ├── img │ │ ├── data_model.png │ │ ├── pow_running.png │ │ └── logo.svg │ ├── api_on_rails.adoc │ ├── chapter00-before.adoc │ ├── chapter02-api.adoc │ └── chapter01-introduction.adoc ├── fr │ ├── img │ │ ├── pow_running.png │ │ ├── logo.svg │ │ └── leanpub-cover.svg │ ├── api_on_rails.adoc │ ├── chapter00-before.adoc │ └── chapter02-api.adoc └── leanpub │ └── cover.svg.png ├── rails5 ├── en │ ├── img │ │ ├── data_model.png │ │ ├── pow_running.png │ │ ├── cover.svg │ │ ├── logo.svg │ │ └── leanpub-cover.svg │ ├── api_on_rails.adoc │ ├── chapter00-before.adoc │ └── chapter04-refactoring-tests.adoc └── fr │ ├── img │ ├── data_model.png │ ├── pow_running.png │ ├── cover.svg │ ├── logo.svg │ └── leanpub-cover.svg │ ├── api_on_rails.adoc │ └── chapter00-before.adoc ├── fonts ├── iAWriterDuospace-Bold.ttf ├── iAWriterDuospace-Italic.ttf ├── iAWriterDuospace-Regular.ttf └── iAWriterDuospace-BoldItalic.ttf ├── .gitignore ├── .gitmodules ├── Gemfile ├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── LICENSE ├── Gemfile.lock ├── README.md ├── Rakefile └── themes └── my-theme.yml /rails7/pt-br/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails7/pt-br/img/logo.png -------------------------------------------------------------------------------- /rails6/pt-br/img/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails6/pt-br/img/cover.png -------------------------------------------------------------------------------- /rails7/pt-br/img/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails7/pt-br/img/cover.png -------------------------------------------------------------------------------- /rails5/en/img/data_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails5/en/img/data_model.png -------------------------------------------------------------------------------- /rails5/en/img/pow_running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails5/en/img/pow_running.png -------------------------------------------------------------------------------- /rails5/fr/img/data_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails5/fr/img/data_model.png -------------------------------------------------------------------------------- /rails5/fr/img/pow_running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails5/fr/img/pow_running.png -------------------------------------------------------------------------------- /rails6/en/img/pow_running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails6/en/img/pow_running.png -------------------------------------------------------------------------------- /rails6/es/img/data_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails6/es/img/data_model.png -------------------------------------------------------------------------------- /rails6/es/img/pow_running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails6/es/img/pow_running.png -------------------------------------------------------------------------------- /rails6/fr/img/pow_running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails6/fr/img/pow_running.png -------------------------------------------------------------------------------- /rails6/leanpub/cover.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails6/leanpub/cover.svg.png -------------------------------------------------------------------------------- /fonts/iAWriterDuospace-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/fonts/iAWriterDuospace-Bold.ttf -------------------------------------------------------------------------------- /rails6/pt-br/img/pow_running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails6/pt-br/img/pow_running.png -------------------------------------------------------------------------------- /rails7/pt-br/img/pow_running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/rails7/pt-br/img/pow_running.png -------------------------------------------------------------------------------- /fonts/iAWriterDuospace-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/fonts/iAWriterDuospace-Italic.ttf -------------------------------------------------------------------------------- /fonts/iAWriterDuospace-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/fonts/iAWriterDuospace-Regular.ttf -------------------------------------------------------------------------------- /fonts/iAWriterDuospace-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madeindjs/api_on_rails/HEAD/fonts/iAWriterDuospace-BoldItalic.ttf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.fdb_latexmk 3 | *.fls 4 | *.log 5 | *.out 6 | *.pdf 7 | *.synctex.gz 8 | *.toc 9 | _minted-api-on-rails 10 | build 11 | .DS_Store 12 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "rails6/code"] 2 | path = rails6/code 3 | url = git@github.com:madeindjs/market_place_api_6.git 4 | [submodule "rails5/code"] 5 | path = rails5/code 6 | url = git@github.com:madeindjs/market_place_api.git 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } 6 | 7 | # gem "rails" 8 | 9 | gem 'asciidoctor', '~> 2.0' 10 | gem "asciidoctor-pdf", "~> 1.5.beta.7" 11 | gem "concurrent-ruby", "~> 1.1" 12 | gem "rouge", "~> 3.3" 13 | gem "asciidoctor-epub3", "~> 1.5.alpha.9" 14 | # TODO: uncomment when issue(https://github.com/tdtds/kindlegen/issues/42) solved 15 | # gem "kindlegen", "~> 3.0" 16 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: alexandre_rousseau 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Rousseau Alexandre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /rails6/en/api_on_rails.adoc: -------------------------------------------------------------------------------- 1 | = API on Rails 6 2 | Alexandre Rousseau 3 | v6.20, 2021-03-25 4 | :doctype: book 5 | :toc: 6 | :imagesdir: img 7 | :title-logo-image: image:logo.svg[] 8 | :homepage: https://github.com/madeindjs/api_on_rails/ 9 | :source-highlighter: rouge 10 | // epub tags 11 | :copyright: CC-BY-SA 4.0, MIT 12 | :keywords: Rails, API, Ruby, Software 13 | :lang: en 14 | :author: Alexandre Rousseau 15 | :description: Learn best practice to build an API using Ruby on Rails 6 16 | :front-cover-image: image:cover.svg[] 17 | :revdate: 2021-03-25 18 | 19 | include::chapter00-before.adoc[] 20 | 21 | <<< 22 | 23 | include::chapter01-introduction.adoc[] 24 | 25 | <<< 26 | 27 | include::chapter02-api.adoc[] 28 | 29 | <<< 30 | 31 | include::chapter03-presenting-users.adoc[] 32 | 33 | <<< 34 | 35 | include::chapter04-authentication.adoc[] 36 | 37 | <<< 38 | 39 | include::chapter05-user-products.adoc[] 40 | 41 | <<< 42 | 43 | include::chapter06-improve-json.adoc[] 44 | 45 | <<< 46 | 47 | include::chapter07-placing-orders.adoc[] 48 | 49 | <<< 50 | 51 | include::chapter08-improve-orders.adoc[] 52 | 53 | <<< 54 | 55 | include::chapter09-optimization.adoc[] 56 | -------------------------------------------------------------------------------- /rails6/fr/api_on_rails.adoc: -------------------------------------------------------------------------------- 1 | = API on Rails 6 2 | Alexandre Rousseau 3 | v6.20, 2021-03-25 4 | :doctype: book 5 | :toc: 6 | :imagesdir: img 7 | :title-logo-image: image:logo.svg[] 8 | :homepage: https://github.com/madeindjs/api_on_rails/ 9 | :source-highlighter: rouge 10 | // epub tags 11 | :copyright: CC-BY-SA 4.0, MIT 12 | :keywords: Rails, API, Ruby, Software 13 | :lang: fr 14 | :author: Alexandre Rousseau 15 | :description: Apprenez les meilleurs pratiques pour construire une API avec Ruby on Rails 6 16 | :front-cover-image: image:cover.svg[] 17 | :revdate: 2021-03-25 18 | 19 | include::chapter00-before.adoc[] 20 | 21 | <<< 22 | 23 | include::chapter01-introduction.adoc[] 24 | 25 | <<< 26 | 27 | include::chapter02-api.adoc[] 28 | 29 | <<< 30 | 31 | include::chapter03-presenting-users.adoc[] 32 | 33 | <<< 34 | 35 | include::chapter04-authentication.adoc[] 36 | 37 | <<< 38 | 39 | include::chapter05-user-products.adoc[] 40 | 41 | <<< 42 | 43 | include::chapter06-improve-json.adoc[] 44 | 45 | <<< 46 | 47 | include::chapter07-placing-orders.adoc[] 48 | 49 | <<< 50 | 51 | include::chapter08-improve-orders.adoc[] 52 | 53 | <<< 54 | 55 | include::chapter09-optimization.adoc[] 56 | -------------------------------------------------------------------------------- /rails6/es/api_on_rails.adoc: -------------------------------------------------------------------------------- 1 | = API on Rails 6 2 | Alexandre Rousseau 3 | v6.20, 2021-03-25 4 | :doctype: book 5 | :toc: 6 | :imagesdir: img 7 | :title-logo-image: image:logo.svg[] 8 | :homepage: https://github.com/madeindjs/api_on_rails/ 9 | :source-highlighter: rouge 10 | // epub tags 11 | :copyright: CC-BY-SA 4.0, MIT 12 | :keywords: Rails, API, Ruby, Software 13 | :lang: es 14 | :author: Alexandre Rousseau, Oscar Téllez 15 | :description: Aprende las mejores prácticas para construir una API usando Ruby on Rails 6 16 | :front-cover-image: image:cover.svg[] 17 | :revdate: 2021-03-25 18 | 19 | include::chapter00-before.adoc[] 20 | 21 | <<< 22 | 23 | include::chapter01-introduction.adoc[] 24 | 25 | <<< 26 | 27 | include::chapter02-api.adoc[] 28 | 29 | <<< 30 | 31 | include::chapter03-presenting-users.adoc[] 32 | 33 | <<< 34 | 35 | include::chapter04-authentication.adoc[] 36 | 37 | <<< 38 | 39 | include::chapter05-user-products.adoc[] 40 | 41 | <<< 42 | 43 | include::chapter06-improve-json.adoc[] 44 | 45 | <<< 46 | 47 | include::chapter07-placing-orders.adoc[] 48 | 49 | <<< 50 | 51 | include::chapter08-improve-orders.adoc[] 52 | 53 | <<< 54 | 55 | include::chapter09-optimization.adoc[] 56 | -------------------------------------------------------------------------------- /rails5/en/api_on_rails.adoc: -------------------------------------------------------------------------------- 1 | = API on Rails 5 2 | Alexandre Rousseau 3 | v6.20, 2021-03-25 4 | :doctype: book 5 | :toc: 6 | :imagesdir: img 7 | :title-logo-image: image:logo.svg[] 8 | :homepage: https://github.com/madeindjs/api_on_rails/ 9 | :source-highlighter: rouge 10 | // epub tags 11 | :copyright: CC-BY-SA 4.0, MIT 12 | :keywords: Rails, API, Ruby, Software 13 | :lang: en 14 | :author: Alexandre Rousseau 15 | :description: Learn best practice to build an API using Ruby on Rails 5 16 | :front-cover-image: image:cover.svg[] 17 | :revdate: 2021-03-25 18 | 19 | include::chapter00-before.adoc[] 20 | 21 | <<< 22 | 23 | include::chapter01-introduction.adoc[] 24 | 25 | <<< 26 | 27 | include::chapter02-api.adoc[] 28 | 29 | <<< 30 | 31 | include::chapter03-presenting-users.adoc[] 32 | 33 | <<< 34 | 35 | include::chapter04-refactoring-tests.adoc[] 36 | 37 | <<< 38 | 39 | include::chapter05-authentication.adoc[] 40 | 41 | <<< 42 | 43 | include::chapter06-user-products.adoc[] 44 | 45 | <<< 46 | 47 | include::chapter07-improve-json.adoc[] 48 | 49 | <<< 50 | 51 | include::chapter08-placing-orders.adoc[] 52 | 53 | <<< 54 | 55 | include::chapter09-improve-orders.adoc[] 56 | 57 | <<< 58 | 59 | include::chapter10-optimization.adoc[] 60 | -------------------------------------------------------------------------------- /rails6/pt-br/api_on_rails.adoc: -------------------------------------------------------------------------------- 1 | = API on Rails 6 2 | Alexandre Rousseau 3 | v6.20, 2021-03-25 4 | :doctype: book 5 | :toc: 6 | :toc-title: Índice 7 | :imagesdir: img 8 | :title-logo-image: image:logo.svg[] 9 | :homepage: https://github.com/madeindjs/api_on_rails/ 10 | :source-highlighter: rouge 11 | // epub tags 12 | :copyright: CC-BY-SA 4.0, MIT 13 | :keywords: Rails, API, Ruby, Software 14 | :lang: pt-br 15 | :author: Alexandre Rousseau, Luiz Carlos dos Santos Junior 16 | :description: Aprenda as melhores práticas para construir uma API utilizando Ruby on Rails 6 17 | :front-cover-image: image:cover.png[] 18 | :revdate: 2023-12-13 19 | 20 | include::chapter00-before.adoc[] 21 | 22 | <<< 23 | 24 | include::chapter01-introduction.adoc[] 25 | 26 | <<< 27 | 28 | include::chapter02-api.adoc[] 29 | 30 | <<< 31 | 32 | include::chapter03-presenting-users.adoc[] 33 | 34 | <<< 35 | 36 | include::chapter04-authentication.adoc[] 37 | 38 | <<< 39 | 40 | include::chapter05-user-products.adoc[] 41 | 42 | <<< 43 | 44 | include::chapter06-improve-json.adoc[] 45 | 46 | <<< 47 | 48 | include::chapter07-placing-orders.adoc[] 49 | 50 | <<< 51 | 52 | include::chapter08-improve-orders.adoc[] 53 | 54 | <<< 55 | 56 | include::chapter09-optimization.adoc[] 57 | -------------------------------------------------------------------------------- /rails5/fr/api_on_rails.adoc: -------------------------------------------------------------------------------- 1 | = API on Rails 5 2 | Alexandre Rousseau 3 | v6.20, 2021-03-25 4 | :doctype: book 5 | :toc: 6 | :imagesdir: img 7 | :title-logo-image: image:logo.svg[] 8 | :homepage: https://github.com/madeindjs/api_on_rails/ 9 | :source-highlighter: rouge 10 | // epub tags 11 | :copyright: CC-BY-SA 4.0, MIT 12 | :keywords: Rails, API, Ruby, Software 13 | :lang: fr 14 | :author: Alexandre Rousseau 15 | :description: Apprenez les meilleurs pratiques pour construire une API avec Ruby on Rails 16 | :front-cover-image: image:cover.svg[] 17 | :revdate: 2021-03-25 18 | 19 | include::chapter00-before.adoc[] 20 | 21 | <<< 22 | 23 | include::chapter01-introduction.adoc[] 24 | 25 | <<< 26 | 27 | include::chapter02-api.adoc[] 28 | 29 | <<< 30 | 31 | include::chapter03-presenting-users.adoc[] 32 | 33 | <<< 34 | 35 | include::chapter04-refactoring-tests.adoc[] 36 | 37 | <<< 38 | 39 | include::chapter05-authentication.adoc[] 40 | 41 | <<< 42 | 43 | include::chapter06-user-products.adoc[] 44 | 45 | <<< 46 | 47 | include::chapter07-improve-json.adoc[] 48 | 49 | <<< 50 | 51 | include::chapter08-placing-orders.adoc[] 52 | 53 | <<< 54 | 55 | include::chapter09-improve-orders.adoc[] 56 | 57 | <<< 58 | 59 | include::chapter10-optimization.adoc[] 60 | -------------------------------------------------------------------------------- /rails7/pt-br/api_on_rails.adoc: -------------------------------------------------------------------------------- 1 | = API on Rails 7 2 | Alexandre Rousseau , Luiz Carlos dos santos Junior 3 | v6.20, 2025-06-04 4 | :doctype: book 5 | :toc: 6 | :toc-title: Índice 7 | :imagesdir: img 8 | :title-logo-image: image:logo.png[] 9 | :homepage: https://github.com/madeindjs/api_on_rails/ 10 | :source-highlighter: rouge 11 | // epub tags 12 | :copyright: CC-BY-SA 4.0, MIT 13 | :keywords: Rails, API, Ruby, Software 14 | :lang: pt-br 15 | :author: Alexandre Rousseau, Luiz Carlos dos Santos Junior 16 | :description: Aprenda as melhores práticas para construir uma API utilizando Ruby on Rails 7 17 | :front-cover-image: image:cover.png[] 18 | :revdate: 2025-04-11 19 | 20 | include::chapter00-before.adoc[] 21 | 22 | <<< 23 | 24 | include::chapter01-introduction.adoc[] 25 | 26 | <<< 27 | 28 | include::chapter02-api.adoc[] 29 | 30 | <<< 31 | 32 | include::chapter03-presenting-users.adoc[] 33 | 34 | <<< 35 | 36 | include::chapter04-authentication.adoc[] 37 | 38 | <<< 39 | 40 | include::chapter05-user-products.adoc[] 41 | 42 | <<< 43 | 44 | include::chapter06-improve-json.adoc[] 45 | 46 | <<< 47 | 48 | include::chapter07-placing-orders.adoc[] 49 | 50 | <<< 51 | 52 | include::chapter08-improve-orders.adoc[] 53 | 54 | <<< 55 | 56 | include::chapter09-optimization.adoc[] 57 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build Book 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: ruby/setup-ruby@v1 14 | with: 15 | ruby-version: 2.7 16 | - run: bundle install 17 | - run: rake build:CI 18 | - uses: actions/github-script@v2 19 | with: 20 | github-token: ${{ secrets.GITHUB_TOKEN }} 21 | script: | 22 | const fs = require('fs').promises; 23 | 24 | const { repo: { owner, repo }, sha } = context; 25 | 26 | const release = await github.repos.createRelease({ 27 | owner, repo, 28 | tag_name: `v6.${process.env.GITHUB_RUN_NUMBER}`, 29 | draft: false, 30 | target_commitish: sha 31 | }); 32 | 33 | console.log('A release has been created'); 34 | const build_dir = 'build'; 35 | 36 | for (let file of await fs.readdir(build_dir)) { 37 | if (file == '.gitkeep') continue; 38 | console.log('uploading', file); 39 | await github.repos.uploadReleaseAsset({ 40 | owner, repo, 41 | release_id: release.data.id, 42 | name: file, 43 | data: await fs.readFile(`${build_dir}/${file}`) 44 | }); 45 | } 46 | console.log('DONE') 47 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | Ascii85 (1.0.3) 5 | addressable (2.7.0) 6 | public_suffix (>= 2.0.2, < 5.0) 7 | afm (0.2.2) 8 | asciidoctor (2.0.10) 9 | asciidoctor-epub3 (1.5.0.alpha.18) 10 | asciidoctor (>= 1.5.6, < 3.0.0) 11 | gepub (~> 1.0.0) 12 | mime-types (~> 3.0) 13 | asciidoctor-pdf (1.5.3) 14 | asciidoctor (>= 1.5.3, < 3.0.0) 15 | concurrent-ruby (~> 1.1.0) 16 | prawn (~> 2.2.0) 17 | prawn-icon (~> 2.5.0) 18 | prawn-svg (~> 0.30.0) 19 | prawn-table (~> 0.2.0) 20 | prawn-templates (~> 0.1.0) 21 | safe_yaml (~> 1.0.0) 22 | thread_safe (~> 0.3.0) 23 | treetop (~> 1.6.0) 24 | ttfunk (~> 1.5.0, >= 1.5.1) 25 | concurrent-ruby (1.1.7) 26 | css_parser (1.7.1) 27 | addressable 28 | gepub (1.0.13) 29 | nokogiri (>= 1.8.2, < 1.12) 30 | rubyzip (> 1.1.1, < 2.4) 31 | hashery (2.1.2) 32 | mime-types (3.3.1) 33 | mime-types-data (~> 3.2015) 34 | mime-types-data (3.2020.0512) 35 | mini_portile2 (2.5.1) 36 | nokogiri (1.11.4) 37 | mini_portile2 (~> 2.5.0) 38 | racc (~> 1.4) 39 | pdf-core (0.7.0) 40 | pdf-reader (2.4.0) 41 | Ascii85 (~> 1.0.0) 42 | afm (~> 0.2.1) 43 | hashery (~> 2.0) 44 | ruby-rc4 45 | ttfunk 46 | polyglot (0.3.5) 47 | prawn (2.2.2) 48 | pdf-core (~> 0.7.0) 49 | ttfunk (~> 1.5) 50 | prawn-icon (2.5.0) 51 | prawn (>= 1.1.0, < 3.0.0) 52 | prawn-svg (0.30.0) 53 | css_parser (~> 1.6) 54 | prawn (>= 0.11.1, < 3) 55 | prawn-table (0.2.2) 56 | prawn (>= 1.3.0, < 3.0.0) 57 | prawn-templates (0.1.2) 58 | pdf-reader (~> 2.0) 59 | prawn (~> 2.2) 60 | public_suffix (4.0.5) 61 | racc (1.5.2) 62 | rouge (3.22.0) 63 | ruby-rc4 (0.1.5) 64 | rubyzip (2.3.0) 65 | safe_yaml (1.0.5) 66 | thread_safe (0.3.6) 67 | treetop (1.6.10) 68 | polyglot (~> 0.3) 69 | ttfunk (1.5.1) 70 | 71 | PLATFORMS 72 | ruby 73 | 74 | DEPENDENCIES 75 | asciidoctor (~> 2.0) 76 | asciidoctor-epub3 (~> 1.5.alpha.9) 77 | asciidoctor-pdf (~> 1.5.beta.7) 78 | concurrent-ruby (~> 1.1) 79 | rouge (~> 3.3) 80 | 81 | BUNDLED WITH 82 | 2.1.4 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Api on Rails 6 3 |

4 | 5 | ![List of sponsors](https://the-godfather.tech/api/v1/badge?repository=https%3A%2F%2Fgithub.com%2Fmadeindjs%2Fapi_on_rails&style=flat&version=1&maxAge=60) 6 | 7 | Learn **best practices** to build an **API** using **Ruby on Rails** 5/6. The intention with this book it's not only to teach you how to build an API with Rails. The purpose is also to teach you how to build **scalable** and **maintainable** API with Rails which means **improve** your current Rails knowledge. In this book you will learn to: 8 | 9 | - Build JSON responses 10 | - Use Git for version controlling 11 | - Testing your endpoints 12 | - Optimize and cache the API 13 | 14 | This book is based on ["APIs on Rails: Building REST APIs with Rails"](http://apionrails.icalialabs.com/book/). It was initially published in 2014 by [Abraham Kuri](https://twitter.com/kurenn). Since the original work was not maintained, I wanted to update this excellent work. All the source code of this book is available in [Asciidoctor](https://asciidoctor.org/) format on this repository. So don't hesitate to [fork the project](https://github.com/madeindjs/api_on_rails/fork) if you want to improve it or fix a mistake that I didn't notice. 15 | 16 | Update & translation of the [API on Rails (EN)](http://apionrails.icalialabs.com/book) book. This book is written using [Asciidoctor](https://asciidoctor.org). 17 | 18 | ## Support the project 19 | 20 | As you may know this project take me some times. So if you want to support me you can buy a version on Leanpub: 21 | 22 | - Rails 5 23 | - [English version](https://leanpub.com/apionrails5/) 24 | - [French version](https://leanpub.com/apionrails5-fr) 25 | - Rails 6 26 | - [English version](https://leanpub.com/apionrails6/) 27 | - [French version](https://leanpub.com/apionrails6-fr) 28 | - [Spanish version](https://leanpub.com/apionrails6-es) (thanks to [Oscar Téllez](https://github.com/oscartzgz)) 29 | 30 | Or you can support me with Liberapay: 31 | 32 | ## Build book 33 | 34 | ```bash 35 | $ git clone https://github.com/madeindjs/api_on_rails/ 36 | $ cd api_on_rails 37 | $ bundle install 38 | $ rake "build:pdf[6,fr]" 39 | ``` 40 | 41 | You can see all build available with `rake -T` 42 | 43 | ```bash 44 | $ rake -T 45 | rake "build:all[version,lang]" # Build all versions 46 | rake "build:epub[version,lang]" # Build an EPUB version 47 | rake "build:html[version,lang]" # Build an HTML version 48 | rake "build:mobi[version,lang]" # Build a MOBI version 49 | rake "build:pdf[version,lang]" # Build a PDF version 50 | ``` 51 | 52 | ## License 53 | 54 | This book is under [MIT license](https://opensource.org/licenses/MIT) and [Creative Common BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) 55 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'asciidoctor' 2 | require 'asciidoctor-pdf' 3 | require 'yaml' 4 | 5 | LANGS = %w[en fr es pt-br].freeze 6 | VERSIONS = %w[5 6 7].freeze 7 | OUTPUT_DIR = File.join __dir__, 'build' 8 | THEMES_DIR = File.join __dir__, 'themes' 9 | FONTS_DIR = File.join __dir__, 'fonts' 10 | 11 | def check_args(args) 12 | lang = args[:lang] 13 | unless LANGS.include?(lang) 14 | msg = format('Lang not available. Select on of these langs: %s', LANGS.join(', ')) 15 | raise ArgumentError, msg 16 | end 17 | 18 | version = args[:version] 19 | unless VERSIONS.include?(version) 20 | msg = format('Version not available. Select on of these versions: %s', VERSIONS.join(', ')) 21 | raise ArgumentError, msg 22 | end 23 | 24 | lang 25 | end 26 | 27 | def in_filename(args) 28 | format('rails%s/%s/api_on_rails.adoc', args[:version], args[:lang]) 29 | end 30 | 31 | def out_filename(args, extension) 32 | format("api_on_rails_%s-%s.%s",args[:version], args[:lang], extension) 33 | end 34 | 35 | namespace :build do 36 | desc 'Build for all versions, languages' 37 | task :CI do 38 | builds = YAML.load(File.read("builds.yaml")) 39 | builds.each do |version, languages| 40 | languages.each do |language| 41 | puts "VERSION: #{version} - LANG: #{language}" 42 | args = { version: version.to_s, lang: language } 43 | Rake::Task['build:pdf'].execute(args) 44 | Rake::Task['build:html'].execute(args) 45 | Rake::Task['build:epub'].execute(args) 46 | # [temporary] no mobi build 47 | # TODO: fix when issue(https://github.com/tdtds/kindlegen/issues/42) solved 48 | # Rake::Task['build:mobi'].execute(args) 49 | end 50 | end 51 | end 52 | 53 | desc 'Build all versions' 54 | task :all, [:version, :lang] do |_task, args| 55 | check_args(args) 56 | Rake::Task['build:pdf'].invoke(args[:version], args[:lang]) 57 | Rake::Task['build:epub'].invoke(args[:version], args[:lang]) 58 | Rake::Task['build:mobi'].invoke(args[:version], args[:lang]) 59 | end 60 | 61 | desc 'Build a PDF version' 62 | task :pdf, [:version, :lang] do |_task, args| 63 | check_args(args) 64 | 65 | input = in_filename args 66 | output = out_filename args, 'pdf' 67 | 68 | Asciidoctor.convert_file input, 69 | safe: :unsafe, 70 | backend: 'pdf', 71 | to_dir: OUTPUT_DIR, 72 | mkdirs: true, 73 | to_file: output, 74 | attributes: { 75 | 'pdf-stylesdir' => THEMES_DIR, 76 | 'pdf-style' => 'my', 77 | 'pdf-fontsdir' => FONTS_DIR, 78 | } 79 | 80 | 81 | # `asciidoctor-pdf #{input} --destination-dir build --out-file #{output}` 82 | puts "Book compiled on build/#{output}" 83 | end 84 | 85 | desc 'Build an HTML version' 86 | task :html, [:version, :lang] do |_task, args| 87 | check_args(args) 88 | input = in_filename args 89 | output = out_filename args, 'html' 90 | `asciidoctor #{input} --destination-dir build --out-file #{output}` 91 | puts "Book compiled on build/#{output}" 92 | end 93 | 94 | desc 'Build an EPUB version' 95 | task :epub, [:version, :lang] do |_task, args| 96 | check_args(args) 97 | input = in_filename args 98 | output = out_filename args, 'epub' 99 | `asciidoctor-epub3 #{input} --destination-dir build --out-file #{output}` 100 | puts "Book compiled on build/#{output}" 101 | end 102 | 103 | desc 'Build a MOBI version' 104 | task :mobi, [:version, :lang] do |_task, args| 105 | check_args(args) 106 | input = in_filename args 107 | output = out_filename args, 'mobi' 108 | `asciidoctor-epub3 #{input} --destination-dir build -a ebook-format=kf8 --out-file #{output}` 109 | puts "Book compiled on build/#{output}" 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /rails5/en/chapter00-before.adoc: -------------------------------------------------------------------------------- 1 | [#chapter00-before] 2 | = Before 3 | 4 | == Foreword 5 | 6 | "API on Rails 5" is based on http://apionrails.icalialabs.com/book/["APIs on Rails: Building REST APIs with Rails"]. It was initially published in 2014 by https://twitter.com/kurenn[Abraham Kuri] under the licenses http://opensource.org/licenses/MIT[MIT] and http://people.freebsd.org/~phk/[Beerware]. 7 | 8 | Since the original work was not maintained, I wanted to update this excellent work and contribute to the Francophone community by translating it myself. This update is also available in the Molière language footnote:[It means french.]. 9 | 10 | == About the author 11 | 12 | https://twitter.com/kurenn[Abraham Kuri] is a Rails developer with 5 years of experience (probably more now). His experience includes working as a freelancer in software product development and more recently in collaboration within the open source community. A graduate in computer science from ITESM, he founded two companies in Mexico (http://icalialabs.com/[Icalia Labs] and http://codeandomexico.org/[Codeando Mexico]). 13 | 14 | On my side, my name is http://rousseau-alexandre.fr[Alexandre Rousseau] and I am a Rails developer with more than 4 years of experience (at the time of writing). I am currently a partner in a company (https://isignif.fr[iSignif]) where I build and maintain a SAAS product using Rails. I also contribute to the Ruby community by producing and maintain some gems that you can consult onhttps://rubygems.org/profiles/madeindjs[my Rubygems.org profile]. Most of my projects are on GitHub so don't http://github.com/madeindjs/[hesitate to follow me]. 15 | 16 | All the source code of this book is available in https://asciidoctor.org/[Asciidoctor] format on https://github.com/madeindjs/api_on_rails[GitHub]. So don't hesitate to https://github.com/madeindjs/api_on_rails/fork[forke] the project if you want to improve it or fix a mistake that I didn't notice. 17 | 18 | == Copyright and license 19 | 20 | This book is provided on http://opensource.org/licenses/MIT[MIT license]. All the book's source code is available on https://fr.wikipedia.org/wiki/Markdown[Markdown] format on https://github.com/madeindjs/api_on_rails[GitHub] 21 | 22 | .MIT license 23 | **** 24 | Copyright 2019 Alexandre Rousseau 25 | 26 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 29 | 30 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | **** 32 | 33 | "API on Rails 5" by https://github.com/madeindjs/api_on_rails[Alexandre Rousseau] is shared according to http://creativecommons.org/licenses/by-sa/4.0/[Creative Commons Attribution - Attribution-ShareAlike 4.0 International]. Built upon this book http://apionrails.icalialabs.com/book/. 34 | 35 | == Thanks 36 | 37 | A big "thank you" to all Github contributors who make this book alive. In alphabetical order: 38 | 39 | * https://github.com/airdry[airdry] 40 | * https://github.com/Landris18[Landris18] 41 | * https://github.com/lex111[lex111] 42 | * https://github.com/cuilei5205189[cuilei5205189] 43 | * https://github.com/franklinjosmell[franklinjosmell] 44 | * https://github.com/notapatch[notapatch] 45 | * https://github.com/promisepreston[promisepreston] 46 | * https://github.com/tacataca[tacataca] 47 | -------------------------------------------------------------------------------- /rails6/en/chapter00-before.adoc: -------------------------------------------------------------------------------- 1 | [#chapter00-before] 2 | = Before 3 | 4 | == Foreword 5 | 6 | "API on Rails 6" is based on http://apionrails.icalialabs.com/book/["APIs on Rails: Building REST APIs with Rails"]. It was initially published in 2014 by https://twitter.com/kurenn[Abraham Kuri] under the licenses http://opensource.org/licenses/MIT[MIT] and http://people.freebsd.org/~phk/[Beerware]. 7 | 8 | The first version was not maintained and was initially planned for Ruby on Rails version 4, which does not https://guides.rubyonrails.org/maintenance_policy.html#security-issues[receive more than security updates]. I wanted to update this excellent book, adapting it to new versions of Ruby on Rails. Therefore, this book is available for Ruby on Rails versions 5.2 and 6.0 (the one you are currently reading). 9 | 10 | NOTE: This book is also available in the Molière language (It means french). 11 | 12 | == About the author 13 | 14 | My name is http://rousseau-alexandre.fr[Alexandre Rousseau], and I am a Rails developer with more than 4 years of experience (at the time of writing). I am currently a partner in a company (https://isignif.fr[iSignif]) to build and maintain a SAAS product using Rails. I also contribute to the Ruby community by producing and maintaining some gems that you can consult on https://rubygems.org/profiles/madeindjs[my Rubygems.org profile]. Most of my projects are on GitHub, then don't hesitate to http://github.com/madeindjs/[follow me]. 15 | 16 | This book's source code is available in https://asciidoctor.org/[Asciidoctor] format on https://github.com/madeindjs/api_on_rails[GitHub]. Feel free to https://github.com/madeindjs/api_on_rails/fork[fork] the project if you want to improve it or fix mistakes I didn't notice. 17 | 18 | == Copyright and license 19 | 20 | This book is provided on http://opensource.org/licenses/MIT[MIT license]. All the book's source code is available on https://fr.wikipedia.org/wiki/Markdown[Markdown] format on https://github.com/madeindjs/api_on_rails[GitHub] 21 | 22 | .MIT license 23 | **** 24 | Copyright 2019 Alexandre Rousseau 25 | 26 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 29 | 30 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | **** 32 | 33 | "API on Rails 6" by https://github.com/madeindjs/api_on_rails[Alexandre Rousseau] is shared according to http://creativecommons.org/licenses/by-sa/4.0/[Creative Commons Attribution - Attribution-ShareAlike 4.0 International]. Built upon this book http://apionrails.icalialabs.com/book/. 34 | 35 | This book's cover picture uses a beautiful photo shot by https://unsplash.com/@siloine?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText[Yoann Siloine] who published it on https://unsplash.com[Unsplash]. 36 | 37 | == Thanks 38 | 39 | A big "thank you" to all Github contributors who keep this book alive. In alphabetical order: 40 | 41 | * https://github.com/airdry[airdry] 42 | * https://github.com/Landris18[Landris18] 43 | * https://github.com/lex111[lex111] 44 | * https://github.com/cuilei5205189[cuilei5205189] 45 | * https://github.com/franklinjosmell[franklinjosmell] 46 | * https://github.com/notapatch[notapatch] 47 | * https://github.com/promisepreston[promisepreston] 48 | * https://github.com/tacataca[tacataca] 49 | -------------------------------------------------------------------------------- /rails6/es/chapter00-before.adoc: -------------------------------------------------------------------------------- 1 | [#chapter00-before] 2 | = Antes 3 | 4 | == Prefacio 5 | 6 | "API on Rails 6" está basado en http://apionrails.icalialabs.com/book/["APIs on Rails: Building REST APIs with Rails"]. Fue publicado inicialmente en 2014 por https://twitter.com/kurenn[Abraham Kuri] bajo la licencia http://opensource.org/licenses/MIT[MIT] y http://people.freebsd.org/~phk/[Beerware]. 7 | 8 | La primera versión no es mantenida y fue planeada para Ruby on Rails 4 la cual no https://guides.rubyonrails.org/maintenance_policy.html#security-issues[recibe más actualizaciones de seguridad]. He buscado actualizar este excelente libro, adaptándolo a nuevas versiones de Ruby on Rails. Este libro está por lo tanto disponible para Ruby on Rails en sus versiones 5.2 y 6.0 (el cual te encuentras leyendo). 9 | 10 | NOTE: Este libro también está disponible en el lenguaje Molière (Esto significa francés). 11 | 12 | == Acerca del autor 13 | 14 | Mi nombre es http://rousseau-alexandre.fr[Alexandre Rousseau] y soy un desarrollador en Rails con más de 4 años de experiencia (al momento de escribirlo). Actualmente soy socio en una compañía (https://isignif.fr[iSignif]) donde construyo y mantengo un producto SAAS usando Rails. También contribuyo a la comunidad Ruby produciendo y manteniendo algunas gemas que puedes consular en https://rubygems.org/profiles/madeindjs[my Rubygems.org profile]. La mayoría de mis proyectos están en GitHub así que no dudes en http://github.com/madeindjs/[seguirme]. 15 | 16 | Todo el código fuente de este libro está en formato https://asciidoctor.org/[Asciidoctor] disponible en https://github.com/madeindjs/api_on_rails[GitHub]. Por lo tanto, siéntete libre de hacer un https://github.com/madeindjs/api_on_rails/fork[fork] al proyecto si quieres mejorarlo o corregir errores que no noté. 17 | 18 | == Derechos de autor y licencia 19 | 20 | Este libro está bajo la http://opensource.org/licenses/MIT[licencia MIT]. Todo el código fuente del libro está en el formato https://fr.wikipedia.org/wiki/Markdown[Markdown] disponible en https://github.com/madeindjs/api_on_rails[GitHub] 21 | 22 | .Licencia MIT 23 | **** 24 | Copyright 2019 Alexandre Rousseau 25 | 26 | Por la presente se concede permiso, libre de cargos, a cualquier persona que obtenga una copia de este software y de los archivos de documentación asociados (el "Software"), a utilizar el Software sin restricción, incluyendo sin limitación los derechos a usar, copiar, modificar, fusionar, publicar, distribuir, sublicenciar, y/o vender copias del Software, y a permitir a las personas a las que se les proporcione el Software a hacer lo mismo, sujeto a las siguientes condiciones: 27 | 28 | El aviso de copyright anterior y este aviso de permiso se incluirán en todas las copias o partes sustanciales del Software. 29 | EL SOFTWARE SE PROPORCIONA "COMO ESTÁ", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO, PERO NO LIMITADO A GARANTÍAS DE COMERCIALIZACIÓN, IDONEIDAD PARA UN PROPÓSITO PARTICULAR E INCUMPLIMIENTO. EN NINGÚN CASO LOS AUTORES O PROPIETARIOS DE LOS DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGUNA RECLAMACIÓN, DAÑOS U OTRAS RESPONSABILIDADES, YA SEA EN UNA ACCIÓN DE CONTRATO, AGRAVIO O CUALQUIER OTRO MOTIVO, DERIVADAS DE, FUERA DE O EN CONEXIÓN CON EL SOFTWARE O SU USO U OTRO TIPO DE ACCIONES EN EL SOFTWARE. 30 | **** 31 | 32 | "API on Rails 6" por https://github.com/madeindjs/api_on_rails[Alexandre Rousseau] es compartido de acuerdo a http://creativecommons.org/licenses/by-sa/4.0/[Creative Commons Attribution - Attribution-ShareAlike 4.0 International]. Construido sobre este libro http://apionrails.icalialabs.com/book/. 33 | 34 | La portada de este libro usa una hermosa foto tomada por https://unsplash.com/@siloine?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText[Yoann Siloine] quien publicó en https://unsplash.com[Unsplash]. 35 | 36 | == Agradecimientos 37 | 38 | Un gran "gracias" a todos los contribuidores de GitHub quienes mantienen este libro vivo. En orden alfabético: 39 | 40 | * https://github.com/airdry[airdry] 41 | * https://github.com/Landris18[Landris18] 42 | * https://github.com/lex111[lex111] 43 | * https://github.com/cuilei5205189[cuilei5205189] 44 | * https://github.com/franklinjosmell[franklinjosmell] 45 | * https://github.com/notapatch[notapatch] 46 | * https://github.com/promisepreston[promisepreston] 47 | * https://github.com/tacataca[tacataca] 48 | -------------------------------------------------------------------------------- /rails5/fr/chapter00-before.adoc: -------------------------------------------------------------------------------- 1 | [#chapter00-before] 2 | = Avant-propos 3 | 4 | "API on Rails 5" est basé sur http://apionrails.icalialabs.com/book/["APIs on Rails: Building REST APIs with Rails"]. Celui-ci fut initialement publié en 2014 par https://twitter.com/kurenn[Abraham Kuri] sous les licences http://opensource.org/licenses/MIT[MIT] et http://people.freebsd.org/~phk/[Beerware]. 5 | 6 | L'œuvre originale étant non maintenue, j'ai voulu mettre à jour cet excellent ouvrage et contribuer à la communauté francophone en le traduisant moi-même. Cette mise à jour est aussi disponible dans la langue de Shakespeare footnote:[C'est-à-dire en anglais.]. 7 | 8 | == A propos de l'auteur original 9 | 10 | https://twitter.com/kurenn[Abraham Kuri] est un développeur Rails avec 5 ans d'expérience (sûrement plus maintenant). Son expérience inclut le travail en tant que _freelance_ dans la construction de produits logiciels et plus récemment dans la collaboration au sein de la communauté open source. Diplômé en informatique d'ITESM, il a fondé deux sociétés au Mexique (http://icalialabs.com/[Icalia Labs] et http://codeandomexico.org/[Codeando Mexico]). 11 | 12 | De mon côté, je m'appelle http://rousseau-alexandre.fr[Alexandre Rousseau] et je suis un développeur Rails avec plus de 4 ans d'expérience (à l'heure où j'écris ces lignes). Je suis actuellement associé dans une entreprise (https://isignif.fr[iSignif]) ou je construis et maintiens un produit de type SAAS en utilisant Rails. Je contribue aussi à la communauté Ruby en produisant et maintenant quelques gemmes que vous pouvez consulter sur https://rubygems.org/profiles/madeindjs[mon profil Rubygems.org]. La plupart de mes projets sont sur GitHub donc http://github.com/madeindjs/[n'hésitez pas à me suivre]. 13 | 14 | Tout le code source de ce livre est disponible au format https://asciidoctor.org[Asciidoctor] sur https://github.com/madeindjs/api_on_rails[GitHub]. Ainsi n'hésitez pas à https://github.com/madeindjs/api_on_rails/fork[forker] le projet si vous voulez l'améliorer ou corriger une faute qui m'aurait échappée. 15 | 16 | == Droits d'auteur et licence 17 | 18 | Cette traduction est disponible sous http://opensource.org/licenses/MIT[licence MIT]. Tout le code source de ce livre est disponible au format https://asciidoctor.org[Asciidoctor] sur https://github.com/madeindjs/api_on_rails[GitHub] 19 | 20 | .licence MIT 21 | **** 22 | La licence MIT Copyright (c) 2019 Alexandre Rousseau 23 | 24 | Permission est accordée, à titre gratuit, à toute personne obtenant une copie de ce logiciel et la documentation associée, pour faire des modification dans le logiciel sans restriction et sans limitation des droits d'utiliser, copier, modifier, fusionner, publier, distribuer, concéder sous licence, et / ou de vendre les copies du Logiciel, et à autoriser les personnes auxquelles le Logiciel est meublé de le faire, sous réserve des conditions suivantes: 25 | 26 | L'avis de copyright ci-dessus et cette autorisation doit être inclus dans toutes les copies ou parties substantielles du Logiciel. 27 | 28 | LE LOGICIEL EST FOURNI «TEL QUEL», SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE, Y COMPRIS, MAIS SANS S'Y LIMITER, LES GARANTIES DE QUALITÉ MARCHANDE, ADAPTATION À UN USAGE PARTICULIER ET D'ABSENCE DE CONTREFAÇON. EN AUCUN CAS LES AUTEURS OU TITULAIRES DU ETRE TENU RESPONSABLE DE TOUT DOMMAGE, RÉCLAMATION OU AUTRES RESPONSABILITÉ, SOIT DANS UNE ACTION DE CONTRAT, UN TORT OU AUTRE, PROVENANT DE, DE OU EN RELATION AVEC LE LOGICIEL OU L'UTILISATION OU DE TRANSACTIONS AUTRES LE LOGICIEL. 29 | **** 30 | 31 | "API on Rails 5" de https://github.com/madeindjs/api_on_rails[Alexandre Rousseau] est mis à disposition selon les termes de la licence http://creativecommons.org/licenses/by-sa/4.0/[Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International]. Fondé sur une œuvre à http://apionrails.icalialabs.com/book/. 32 | 33 | == Merci 34 | 35 | Un grand merci à tous les contributeurs de Github qui rendent ce livre vivant. Par ordre alphabétique : 36 | 37 | * https://github.com/airdry[airdry] 38 | * https://github.com/Landris18[Landris18] 39 | * https://github.com/lex111[lex111] 40 | * https://github.com/cuilei5205189[cuilei5205189] 41 | * https://github.com/franklinjosmell[franklinjosmell] 42 | * https://github.com/notapatch[notapatch] 43 | * https://github.com/promisepreston[promisepreston] 44 | * https://github.com/tacataca[tacataca] 45 | -------------------------------------------------------------------------------- /rails6/fr/chapter00-before.adoc: -------------------------------------------------------------------------------- 1 | [#chapter00-before] 2 | = Avant-propos 3 | 4 | "API on Rails 6" est basé sur http://apionrails.icalialabs.com/book/["APIs on Rails: Building REST APIs with Rails"]. Celui-ci fut initialement publié en 2014 par https://twitter.com/kurenn[Abraham Kuri] sous les licences http://opensource.org/licenses/MIT[MIT] et http://people.freebsd.org/~phk/[Beerware]. 5 | 6 | Cette première version, non maintenue, était prévue pour la version 4 de Ruby on Rails qui ne https://guides.rubyonrails.org/maintenance_policy.html#security-issues[reçoit plus que les mises à jour de sécurité]. J'ai voulu mettre à jour cet excellent ouvrage et contribuer à la communauté francophone en le traduisant moi-même et en l'adaptant aux nouvelles versions de Ruby on Rails. Ce livre est donc disponible pour la version 5.2 de Ruby on Rail et la version 6.0 (celle que vous lisez actuellement). 7 | 8 | NOTE: Ce livre est aussi disponible dans la langue de Shakespeare. 9 | 10 | Dans cette version je n'ai pas seulement cherché à rendre les exemples compatibles mais j'ai aussi voulu simplifier la mise en place d'une API avec Rails en utilisant des librairies plus récentes et surtout: maintenues. 11 | 12 | == A propos de l'auteur original 13 | 14 | Je m'appelle http://rousseau-alexandre.fr[Alexandre Rousseau] et je suis un développeur Rails passionné avec plus de 4 ans d'expérience (à l'heure où j'écris ces lignes). Je suis actuellement associé chez (https://isignif.fr[iSignif SAS]) où je construis et maintiens un produit de type SAAS en utilisant Rails. Je contribue aussi à la communauté Ruby en produisant et maintenant quelques gemmes que vous pouvez consulter sur https://rubygems.org/profiles/madeindjs[mon profil Rubygems.org]. La plupart de mes projets sont sur GitHub donc http://github.com/madeindjs/[n'hésitez pas à me suivre]. 15 | 16 | Tout le code source de ce livre est disponible au format https://asciidoctor.org[Asciidoctor] sur https://github.com/madeindjs/api_on_rails[GitHub]. Ainsi n'hésitez pas à https://github.com/madeindjs/api_on_rails/fork[forker] le projet si vous voulez l'améliorer ou corriger une faute qui m'aurait échappée. 17 | 18 | == Droits d'auteur et licence 19 | 20 | Cette traduction est disponible sous http://opensource.org/licenses/MIT[licence MIT]. Tout le code source de ce livre est disponible au format https://asciidoctor.org[Asciidoctor] sur https://github.com/madeindjs/api_on_rails[GitHub] 21 | 22 | .licence MIT 23 | **** 24 | La licence MIT Copyright (c) 2019 Alexandre Rousseau 25 | 26 | La permission est accordée, à titre gratuit, à toute personne obtenant une copie de ce logiciel et la documentation associée, pour faire des modifications dans le logiciel sans restriction et sans limitation des droits d'utiliser, copier, modifier, fusionner, publier, distribuer, concéder sous licence, et / ou de vendre les copies du Logiciel, et à autoriser les personnes auxquelles le Logiciel est meublé de le faire, sous réserve des conditions suivantes: 27 | 28 | L'avis de copyright ci-dessus et cette autorisation doivent être inclus dans toutes les copies ou parties substantielles du Logiciel. 29 | 30 | LE LOGICIEL EST FOURNI «TEL QUEL», SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE, Y COMPRIS, MAIS SANS S'Y LIMITER, LES GARANTIES DE QUALITÉ MARCHANDE, ADAPTATION À UN USAGE PARTICULIER ET D'ABSENCE DE CONTREFAÇON. EN AUCUN CAS LES AUTEURS OU TITULAIRES DOIVENT ÊTRE TENUS RESPONSABLE DE TOUT DOMMAGE, RÉCLAMATION OU AUTRES RESPONSABILITÉS, SOIT DANS UNE ACTION DE CONTRAT, UN TORT OU AUTRE, PROVENANT DE, DE OU EN RELATION AVEC LE LOGICIEL OU L'UTILISATION OU DE TRANSACTIONS AUTRES LE LOGICIEL. 31 | **** 32 | 33 | "API on Rails 6" de https://github.com/madeindjs/api_on_rails[Alexandre Rousseau] est mis à disposition selon les termes de la licence http://creativecommons.org/licenses/by-sa/4.0/[Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International]. Fondé sur une œuvre à http://apionrails.icalialabs.com/book/. 34 | 35 | == Merci 36 | 37 | Un grand merci à tous les contributeurs de Github qui rendent ce livre vivant. Par ordre alphabétique : 38 | 39 | * https://github.com/airdry[airdry] 40 | * https://github.com/Landris18[Landris18] 41 | * https://github.com/lex111[lex111] 42 | * https://github.com/cuilei5205189[cuilei5205189] 43 | * https://github.com/franklinjosmell[franklinjosmell] 44 | * https://github.com/notapatch[notapatch] 45 | * https://github.com/promisepreston[promisepreston] 46 | * https://github.com/tacataca[tacataca] 47 | -------------------------------------------------------------------------------- /rails6/pt-br/chapter00-before.adoc: -------------------------------------------------------------------------------- 1 | [#chapter00-before] 2 | = Antes 3 | 4 | == Prefácio 5 | 6 | "API on Rails 6" é baseado no livro http://apionrails.icalialabs.com/book/["APIs on Rails: Building REST APIs with Rails"]. Ele foi inicialmente publicado em 2014 por https://twitter.com/kurenn[Abraham Kuri] sob as licenças http://opensource.org/licenses/MIT[MIT] e http://people.freebsd.org/~phk/[Beerware]. 7 | 8 | A primeira versão não foi mantida e foi inicialmente planejada para a versão 4 do Ruby on Rails, que não https://guides.rubyonrails.org/maintenance_policy.html#security-issues[recebe mais atualizações de segurança]. Eu quis atualizar este excelente livro, adaptando-o para novas versões do Ruby on Rails. Contudo, este livro está disponível para as versões 5.2, 6.0 (a que você está lendo no momento) e 6.1 do Ruby on Rails. 9 | 10 | NOTE: Este livro está disponível em francês, Inglês, Espanhol e Português. 11 | 12 | == Sobre os autores 13 | 14 | === Alexandre Rousseau 15 | 16 | Meu nome é http://rousseau-alexandre.fr[Alexandre Rousseau], e eu sou um desenvolvedor Rails com mais de 4 anos de experiência (até o momento em que escrevo). Eu sou no momento um parceiro em uma compania (https://isignif.fr[iSignif]) para contruir e manter um produto SAAS utilizando Rails. Eu também contribuo para a comunidade Ruby, produzindo e mantendo algumas gems que você pode consultar no https://rubygems.org/profiles/madeindjs[meu perfil em Rubygems.org]. A maioria dos meus projetos está no GitHub, logo, não hesite em http://github.com/madeindjs/[me seguir]. 17 | 18 | O código fonte deste livro está disponível no formato https://asciidoctor.org/[Asciidoctor] em https://github.com/madeindjs/api_on_rails[GitHub]. Sinta-se livre para https://github.com/madeindjs/api_on_rails/fork[fazer um fork] do projeto se você quiser melhorá-lo ou corrigir erros que eu não tenha notado. 19 | 20 | === Luiz Carlos dos Santos Junior 21 | 22 | Desenvolvedor Web com mais de 13 anos de experiência, trabalhando tanto com desenvolvimento frontend, como com backend. Bacharel em Ciência da Computação, Pós-graduado em MBA em Tecnologia da Informação e Licenciado em Filosofia. 23 | 24 | Editor da versão em Português. 25 | 26 | Acompanhe os meus projetos no http://github.com/luizbinario/[Github]. 27 | 28 | == Copyright e licensa 29 | 30 | Este livro é disponibilizado sob http://opensource.org/licenses/MIT[licensa do MIT]. Todo o código fonte do livro está disponível no formato https://fr.wikipedia.org/wiki/Markdown[Markdown] no https://github.com/madeindjs/api_on_rails[GitHub] 31 | 32 | .Licensa MIT 33 | **** 34 | Copyright 2019 Alexandre Rousseau 35 | 36 | A permissão é aqui concedida, sem nenhum custo, a qualquer pessoa que obtenha uma cópia deste software e dos arquivos de documentação associados (o "Software"), para lidar com o Software sem restrições, incluindo, sem limitação, os direitos de usar, copiar, modificar, mesclar, publicar, distribuir, sublicenciar e/ou vender cópias do Software e permitir que as pessoas a quem o Software é fornecido façam o mesmo, sujeito às seguintes condições: 37 | 38 | O aviso de direitos autorais acima e este aviso de permissão devem ser incluídos em todas as cópias ou partes substanciais do Software. 39 | 40 | O SOFTWARE É FORNECIDO "COMO ESTÁ", SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO ÀS GARANTIAS DE COMERCIALIZAÇÃO, ADEQUAÇÃO A UM DETERMINADO FIM E NÃO INFRAÇÃO. EM NENHUM CASO OS AUTORES OU DETENTORES DE DIREITOS AUTORAIS SERÃO RESPONSÁVEIS POR QUALQUER REIVINDICAÇÃO, DANOS OU OUTRA RESPONSABILIDADE, SEJA EM AÇÃO DE CONTRATO, INDENIZAÇÃO OU DE OUTRA FORMA, DECORRENTE, FORA OU EM CONEXÃO COM O SOFTWARE OU O USO OU OUTRAS NEGOCIAÇÕES NO SOFTWARE. 41 | **** 42 | 43 | "API on Rails 6" por https://github.com/madeindjs/api_on_rails[Alexandre Rousseau] é compartilhado de acordo com a http://creativecommons.org/licenses/by-sa/4.0/[Creative Commons Attribution - Attribution-ShareAlike 4.0 International]. Construído sobre este livro: http://apionrails.icalialabs.com/book/. 44 | 45 | == Agradecimentos 46 | 47 | Um grande "Obrigado" à todos os colaboradores do Github que mantiveram este livro vivo. Em ordem alfabética: 48 | 49 | * https://github.com/airdry[airdry] 50 | * https://github.com/aleksandrilyin[aleksandrilyin] 51 | * https://github.com/bit4bit[bit4bit] 52 | * https://github.com/crazyoptimist[crazyoptimist] 53 | * https://github.com/cuilei5205189[cuilei5205189] 54 | * https://github.com/dianedelallee[dianedelallee] 55 | * https://github.com/ForerunnerG34[ForerunnerG34] 56 | * https://github.com/franklinjosmell[franklinjosmell] 57 | * https://github.com/itsjustkevin[itsjustkevin] 58 | * https://github.com/j0eii[j0eii] 59 | * https://github.com/kerolloz[kerolloz] 60 | * https://github.com/lex111[lex111] 61 | * https://github.com/luizbinario[luizbinario] 62 | * https://github.com/notapatch[notapatch] 63 | * https://github.com/oscartzgz[oscartzgz] 64 | * https://github.com/promisepreston[promisepreston] 65 | * https://github.com/tacataca[tacataca] 66 | * https://github.com/tavofigse[tavofigse] 67 | * https://github.com/Zovube[Zovube] 68 | 69 | -------------------------------------------------------------------------------- /rails7/pt-br/chapter00-before.adoc: -------------------------------------------------------------------------------- 1 | [#chapter00-before] 2 | = ****** 3 | 4 | == Prefácio 5 | 6 | "API on Rails 7" é baseado no livro http://apionrails.icalialabs.com/book/["APIs on Rails: Building REST APIs with Rails"]. Ele foi inicialmente publicado em 2014 por https://twitter.com/kurenn[Abraham Kuri] sob as licenças http://opensource.org/licenses/MIT[MIT] e http://people.freebsd.org/~phk/[Beerware]. 7 | 8 | A primeira versão não foi mantida e foi inicialmente planejada para a versão 4 do Ruby on Rails, que não https://guides.rubyonrails.org/maintenance_policy.html#security-issues[recebe mais atualizações de segurança]. Eu quis atualizar este excelente livro, adaptando-o para novas versões do Ruby on Rails. Contudo, este livro está disponível para as versões 5.2, 6.0, 6.1 e 7.0 (a que você está lendo no momento) do Ruby on Rails. 9 | 10 | NOTE: Este livro está disponível em francês, Inglês, Espanhol e Português. 11 | 12 | == Sobre os autores 13 | 14 | === Alexandre Rousseau 15 | 16 | Meu nome é http://rousseau-alexandre.fr[Alexandre Rousseau], e eu sou um desenvolvedor Rails com mais de 4 anos de experiência (até o momento em que escrevo). Eu sou no momento um parceiro em uma compania (https://isignif.fr[iSignif]) para contruir e manter um produto SAAS utilizando Rails. Eu também contribuo para a comunidade Ruby, produzindo e mantendo algumas gems que você pode consultar no https://rubygems.org/profiles/madeindjs[meu perfil em Rubygems.org]. A maioria dos meus projetos está no GitHub, logo, não hesite em http://github.com/madeindjs/[me seguir]. 17 | 18 | O código fonte deste livro está disponível no formato https://asciidoctor.org/[Asciidoctor] em https://github.com/madeindjs/api_on_rails[GitHub]. Sinta-se livre para https://github.com/madeindjs/api_on_rails/fork[fazer um fork] do projeto se você quiser melhorá-lo ou corrigir erros que eu não tenha notado. 19 | 20 | === Luiz Carlos dos Santos Junior 21 | 22 | Desenvolvedor Web com mais de 13 anos de experiência, trabalhando tanto com desenvolvimento frontend, como com backend. Bacharel em Ciência da Computação, Pós-graduado em MBA em Tecnologia da Informação e Licenciado em Filosofia. 23 | 24 | Responsável pela edição, adaptação e atualização da versão em português do livro "API on Rails 7", originalmente escrito por Alexandre Rousseau. 25 | 26 | Acompanhe os meus projetos no http://github.com/luizbinario/[Github]. 27 | 28 | == Copyright e licensa 29 | 30 | Este livro é disponibilizado sob http://opensource.org/licenses/MIT[licensa do MIT]. Todo o código fonte do livro está disponível no formato https://fr.wikipedia.org/wiki/Markdown[Markdown] no https://github.com/madeindjs/api_on_rails[GitHub] 31 | 32 | .Licensa MIT 33 | **** 34 | Copyright 2019 Alexandre Rousseau 35 | 36 | A permissão é aqui concedida, sem nenhum custo, a qualquer pessoa que obtenha uma cópia deste software e dos arquivos de documentação associados (o "Software"), para lidar com o Software sem restrições, incluindo, sem limitação, os direitos de usar, copiar, modificar, mesclar, publicar, distribuir, sublicenciar e/ou vender cópias do Software e permitir que as pessoas a quem o Software é fornecido façam o mesmo, sujeito às seguintes condições: 37 | 38 | O aviso de direitos autorais acima e este aviso de permissão devem ser incluídos em todas as cópias ou partes substanciais do Software. 39 | 40 | O SOFTWARE É FORNECIDO "COMO ESTÁ", SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO ÀS GARANTIAS DE COMERCIALIZAÇÃO, ADEQUAÇÃO A UM DETERMINADO FIM E NÃO INFRAÇÃO. EM NENHUM CASO OS AUTORES OU DETENTORES DE DIREITOS AUTORAIS SERÃO RESPONSÁVEIS POR QUALQUER REIVINDICAÇÃO, DANOS OU OUTRA RESPONSABILIDADE, SEJA EM AÇÃO DE CONTRATO, INDENIZAÇÃO OU DE OUTRA FORMA, DECORRENTE, FORA OU EM CONEXÃO COM O SOFTWARE OU O USO OU OUTRAS NEGOCIAÇÕES NO SOFTWARE. 41 | **** 42 | 43 | "API on Rails 7" por https://github.com/madeindjs/api_on_rails[Alexandre Rousseau] é compartilhado de acordo com a http://creativecommons.org/licenses/by-sa/4.0/[Creative Commons Attribution - Attribution-ShareAlike 4.0 International]. Construído sobre este livro: http://apionrails.icalialabs.com/book/. 44 | 45 | Esta versão em português foi adaptada, revisada e editada por Luiz Carlos dos Santos Junior, com base na obra original de Alexandre Rousseau, conforme os termos da licença Creative Commons Attribution-ShareAlike 4.0 International. 46 | Fonte original: https://github.com/madeindjs/api_on_rails 47 | 48 | == Agradecimentos 49 | 50 | Um grande "Obrigado" à todos os colaboradores do Github que mantiveram este livro vivo. Em ordem alfabética: 51 | 52 | * https://github.com/airdry[airdry] 53 | * https://github.com/aleksandrilyin[aleksandrilyin] 54 | * https://github.com/bit4bit[bit4bit] 55 | * https://github.com/crazyoptimist[crazyoptimist] 56 | * https://github.com/cuilei5205189[cuilei5205189] 57 | * https://github.com/dianedelallee[dianedelallee] 58 | * https://github.com/ForerunnerG34[ForerunnerG34] 59 | * https://github.com/franklinjosmell[franklinjosmell] 60 | * https://github.com/itsjustkevin[itsjustkevin] 61 | * https://github.com/j0eii[j0eii] 62 | * https://github.com/kerolloz[kerolloz] 63 | * https://github.com/lex111[lex111] 64 | * https://github.com/luizbinario[luizbinario] 65 | * https://github.com/notapatch[notapatch] 66 | * https://github.com/oscartzgz[oscartzgz] 67 | * https://github.com/promisepreston[promisepreston] 68 | * https://github.com/tacataca[tacataca] 69 | * https://github.com/tavofigse[tavofigse] 70 | * https://github.com/Zovube[Zovube] 71 | 72 | -------------------------------------------------------------------------------- /rails5/en/img/cover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 19 | 20 | 27 | {"author": "Alexandre Rousseau"} 37 | 40 | 43 | "APIonRails":5 63 | 67 | 72 | 77 | 82 | 87 | 88 | { 98 | } 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /rails5/fr/img/cover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 19 | 20 | 27 | {"author": "Alexandre Rousseau"} 37 | 40 | 43 | "APIonRails":5 63 | 67 | 72 | 77 | 82 | 87 | 88 | { 98 | } 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /rails5/en/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | "APIonRails":5 84 | 88 | 94 | 100 | 106 | 112 | 113 | { 124 | } 135 | 136 | 137 | 139 | 140 | -------------------------------------------------------------------------------- /rails5/fr/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | "APIonRails":5 84 | 88 | 94 | 100 | 106 | 112 | 113 | { 124 | } 135 | 136 | 137 | 139 | 140 | -------------------------------------------------------------------------------- /rails6/en/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | "APIonRails":6 84 | 88 | 94 | 100 | 106 | 112 | 113 | { 124 | } 135 | 136 | 137 | 139 | 140 | -------------------------------------------------------------------------------- /rails6/es/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | "APIonRails":6 84 | 88 | 94 | 100 | 106 | 112 | 113 | { 124 | } 135 | 136 | 137 | 139 | 140 | -------------------------------------------------------------------------------- /rails6/fr/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | "APIonRails":6 84 | 88 | 94 | 100 | 106 | 112 | 113 | { 124 | } 135 | 136 | 137 | 139 | 140 | -------------------------------------------------------------------------------- /rails6/pt-br/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | "APIonRails":6 84 | 88 | 94 | 100 | 106 | 112 | 113 | { 124 | } 135 | 136 | 137 | 139 | 140 | -------------------------------------------------------------------------------- /rails7/pt-br/img/old-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | "APIonRails":6 84 | 88 | 94 | 100 | 106 | 112 | 113 | { 124 | } 135 | 136 | 137 | 139 | 140 | -------------------------------------------------------------------------------- /rails5/en/img/leanpub-cover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 44 | 46 | 47 | 49 | image/svg+xml 50 | 52 | 53 | 54 | 55 | 56 | 61 | 68 | {"author": "Alexandre Rousseau"} 79 | 83 | 86 | "APIonRails":5 107 | 111 | 117 | 123 | 129 | 135 | 136 | { 147 | } 158 | 159 | 160 | 161 | 163 | 165 | 166 | -------------------------------------------------------------------------------- /rails5/fr/img/leanpub-cover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 44 | 46 | 47 | 49 | image/svg+xml 50 | 52 | 53 | 54 | 55 | 56 | 61 | 68 | {"author": "Alexandre Rousseau"} 79 | 83 | 86 | "APIonRails":5 107 | 111 | 117 | 123 | 129 | 135 | 136 | { 147 | } 158 | 159 | 160 | 161 | 163 | 165 | 166 | -------------------------------------------------------------------------------- /rails6/fr/img/leanpub-cover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 44 | 46 | 47 | 49 | image/svg+xml 50 | 52 | 53 | 54 | 55 | 56 | 61 | 68 | {"author": "Alexandre Rousseau"} 79 | 83 | 86 | "APIonRails":6 107 | 111 | 117 | 123 | 129 | 135 | 136 | { 147 | } 158 | 159 | 160 | 161 | 163 | 165 | 166 | -------------------------------------------------------------------------------- /themes/my-theme.yml: -------------------------------------------------------------------------------- 1 | font: 2 | catalog: 3 | Duospace: 4 | normal: iAWriterDuospace-Regular.ttf 5 | bold: iAWriterDuospace-Bold.ttf 6 | italic: iAWriterDuospace-Italic.ttf 7 | bold_italic: iAWriterDuospace-BoldItalic.ttf 8 | 9 | page: 10 | background_color: ffffff 11 | layout: portrait 12 | margin: [1in, 1in, 1in, 1in] 13 | # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress 14 | margin_inner: 0.75in 15 | margin_outer: 0.59in 16 | size: A4 17 | base: 18 | align: justify 19 | # color as hex string (leading # is optional) 20 | font_color: 333333 21 | # color as RGB array 22 | #font_color: [51, 51, 51] 23 | # color as CMYK array (approximated) 24 | #font_color: [0, 0, 0, 0.92] 25 | #font_color: [0, 0, 0, 92%] 26 | font_family: Duospace 27 | # font_family: Times-Roman 28 | # choose one of these font_size/line_height_length combinations 29 | #font_size: 14 30 | #line_height_length: 20 31 | #font_size: 11.25 32 | #line_height_length: 18 33 | #font_size: 11.2 34 | #line_height_length: 16 35 | font_size: 10.5 36 | #line_height_length: 15 37 | # correct line height for Noto Serif metrics 38 | line_height_length: 12 39 | #font_size: 11.25 40 | #line_height_length: 18 41 | line_height: $base_line_height_length / $base_font_size 42 | font_size_large: round($base_font_size * 1.25) 43 | font_size_small: round($base_font_size * 0.85) 44 | font_size_min: $base_font_size * 0.75 45 | font_style: normal 46 | border_color: eeeeee 47 | border_radius: 4 48 | border_width: 0.5 49 | # FIXME vertical_rhythm is weird; we should think in terms of ems 50 | #vertical_rhythm: $base_line_height_length * 2 / 3 51 | # correct line height for Noto Serif metrics (comes with built-in line height) 52 | vertical_rhythm: $base_line_height_length 53 | horizontal_rhythm: $base_line_height_length 54 | # QUESTION should vertical_spacing be block_spacing instead? 55 | vertical_spacing: $vertical_rhythm 56 | link: 57 | font_color: 428bca 58 | # literal is currently used for inline monospaced in prose and table cells 59 | literal: 60 | font_color: b12146 61 | font_family: $base_font_family 62 | menu_caret_content: " \u203a " 63 | heading: 64 | align: left 65 | #font_color: 181818 66 | font_color: $base_font_color 67 | font_family: $base_font_family 68 | font_style: bold 69 | # h1 is used for part titles (book doctype) or the doctitle (article doctype) 70 | h1_font_size: floor($base_font_size * 2.6) 71 | # h2 is used for chapter titles (book doctype only) 72 | h2_font_size: floor($base_font_size * 2.15) 73 | h3_font_size: round($base_font_size * 1.7) 74 | h4_font_size: $base_font_size_large 75 | h5_font_size: $base_font_size 76 | h6_font_size: $base_font_size_small 77 | #line_height: 1.4 78 | # correct line height for Noto Serif metrics (comes with built-in line height) 79 | line_height: 1 80 | margin_top: $vertical_rhythm * 0.4 81 | margin_bottom: $vertical_rhythm * 0.9 82 | title_page: 83 | align: right 84 | logo: 85 | top: 10% 86 | title: 87 | top: 70% 88 | font_size: $heading_h1_font_size 89 | font_color: 999999 90 | line_height: 0.9 91 | subtitle: 92 | font_size: $heading_h3_font_size 93 | font_style: bold_italic 94 | line_height: 1 95 | authors: 96 | margin_top: $base_font_size * 1.25 97 | font_size: $base_font_size_large 98 | font_color: 181818 99 | revision: 100 | margin_top: $base_font_size * 1.25 101 | block: 102 | margin_top: 0 103 | margin_bottom: $vertical_rhythm 104 | caption: 105 | align: left 106 | font_size: $base_font_size * 0.95 107 | font_style: italic 108 | # FIXME perhaps set line_height instead of / in addition to margins? 109 | margin_inside: $vertical_rhythm / 3 110 | #margin_inside: $vertical_rhythm / 4 111 | margin_outside: 0 112 | lead: 113 | font_size: $base_font_size_large 114 | line_height: 1.4 115 | abstract: 116 | font_color: 5c6266 117 | font_size: $lead_font_size 118 | line_height: $lead_line_height 119 | font_style: italic 120 | first_line_font_style: bold 121 | title: 122 | align: center 123 | font_color: $heading_font_color 124 | font_family: $heading_font_family 125 | font_size: $heading_h4_font_size 126 | font_style: $heading_font_style 127 | admonition: 128 | column_rule_color: $base_border_color 129 | column_rule_width: $base_border_width 130 | padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] 131 | #icon: 132 | # tip: 133 | # name: fa-lightbulb-o 134 | # stroke_color: 111111 135 | # size: 24 136 | label: 137 | text_transform: uppercase 138 | font_style: bold 139 | blockquote: 140 | font_color: $base_font_color 141 | font_size: $base_font_size 142 | border_color: $base_border_color 143 | border_width: 5 144 | # FIXME disable negative padding bottom once margin collapsing is implemented 145 | padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] 146 | cite_font_size: $base_font_size_small 147 | cite_font_color: 999999 148 | # code is used for source blocks (perhaps change to source or listing?) 149 | code: 150 | font_color: $base_font_color 151 | font_family: $literal_font_family 152 | font_size: ceil($base_font_size) 153 | padding: $code_font_size 154 | line_height: 1.1 155 | # line_gap is an experimental property to control how a background color is applied to an inline block element 156 | line_gap: 3.8 157 | background_color: f5f5f5 158 | # border_color: cccccc 159 | # border_radius: $base_border_radius 160 | border_width: 0.75 161 | conum: 162 | font_family: Duospace 163 | font_color: $literal_font_color 164 | font_size: $base_font_size 165 | line_height: 4 / 3 166 | example: 167 | border_color: $base_border_color 168 | border_radius: $base_border_radius 169 | border_width: 0.75 170 | background_color: ffffff 171 | # FIXME reenable padding bottom once margin collapsing is implemented 172 | padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] 173 | image: 174 | align: left 175 | prose: 176 | margin_top: $block_margin_top 177 | margin_bottom: $block_margin_bottom 178 | sidebar: 179 | background_color: eeeeee 180 | border_color: e1e1e1 181 | border_radius: $base_border_radius 182 | border_width: $base_border_width 183 | # FIXME reenable padding bottom once margin collapsing is implemented 184 | padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] 185 | title: 186 | align: center 187 | font_color: $heading_font_color 188 | font_family: $heading_font_family 189 | font_size: $heading_h4_font_size 190 | font_style: $heading_font_style 191 | thematic_break: 192 | border_color: $base_border_color 193 | border_style: solid 194 | border_width: $base_border_width 195 | margin_top: $vertical_rhythm * 0.5 196 | margin_bottom: $vertical_rhythm * 1.5 197 | description_list: 198 | term_font_style: bold 199 | term_spacing: $vertical_rhythm / 4 200 | description_indent: $horizontal_rhythm * 1.25 201 | outline_list: 202 | indent: $horizontal_rhythm * 1.5 203 | #marker_font_color: 404040 204 | # NOTE outline_list_item_spacing applies to list items that do not have complex content 205 | item_spacing: $vertical_rhythm / 2 206 | table: 207 | background_color: $page_background_color 208 | #head_background_color: 209 | #head_font_color: $base_font_color 210 | head_font_style: bold 211 | #body_background_color: 212 | body_stripe_background_color: f9f9f9 213 | foot_background_color: f0f0f0 214 | border_color: dddddd 215 | border_width: $base_border_width 216 | cell_padding: 3 217 | toc: 218 | indent: $horizontal_rhythm 219 | line_height: 1.2 220 | dot_leader: 221 | #content: ". " 222 | font_color: a9a9a9 223 | #levels: 2 3 224 | # NOTE in addition to footer, header is also supported 225 | footer: 226 | font_size: $base_font_size_small 227 | # NOTE if background_color is set, background and border will span width of page 228 | border_color: dddddd 229 | border_width: 0.25 230 | height: $base_line_height_length * 2.5 231 | line_height: 1 232 | padding: [$base_line_height_length / 2, 1, 0, 1] 233 | vertical_align: top 234 | #image_vertical_align: or 235 | # additional attributes for content: 236 | # * {page-count} 237 | # * {page-number} 238 | # * {document-title} 239 | # * {document-subtitle} 240 | # * {chapter-title} 241 | # * {section-title} 242 | # * {section-or-chapter-title} 243 | recto: 244 | #columns: "<50% =0% >50%" 245 | right: 246 | content: '{page-number}' 247 | #content: '{section-or-chapter-title} | {page-number}' 248 | #content: '{document-title} | {page-number}' 249 | #center: 250 | # content: '{page-number}' 251 | verso: 252 | #columns: $footer_recto_columns 253 | left: 254 | content: $footer_recto_right_content 255 | #content: '{page-number} | {chapter-title}' 256 | #center: 257 | # content: '{page-number}' 258 | -------------------------------------------------------------------------------- /rails6/es/chapter02-api.adoc: -------------------------------------------------------------------------------- 1 | [#chapter02-api] 2 | = La API 3 | 4 | En esta sección resumiré la aplicación. Hasta aquí ya debiste leer el capítulo anterior. Si no lo has leído te recomiendo que lo hagas. 5 | 6 | Puedes clonar el proyecto hasta este punto con: 7 | 8 | [source,bash] 9 | ---- 10 | $ git checkout tags/checkpoint_chapter02 11 | ---- 12 | 13 | Resumiendo, simplemente generamos nuestra aplicación Rails e hicimos el primer commit. 14 | 15 | == Planificando la aplicación 16 | 17 | Como queremos que la aplicación sea sencilla, esta consistirá de 5 modelos. No te preocupes si no entiendes completamente que estamos haciendo. Vamos a revisar y a construir cada uno de los recursos a medida que avancemos con el tutorial. 18 | 19 | image:data_model.png[Esquema conexiones entre los modelos] 20 | 21 | Resumiendo, el `user`(usuario) podrá realizar muchas `orders`(ordenes/pedidos), subir múltiples `products`(productos) los cuales pueden tener muchas `images`(imágenes) ó `comments`(comentarios) de otros usuarios de la aplicación. 22 | 23 | No construiremos vistas para mostrar o interactuar con la API, así que no hagas de esto un gran tutorial. Para ello hay muchas opciones allá afuera como los frameworks de javascript (https://angularjs.org/[Angular], https://vuejs.org/[Vue.js], https://reactjs.org/[React.js]). 24 | 25 | Hasta este punto deberías preguntarte: 26 | 27 | > ¿Esta bien, pero, yo necesito explorar o visualizar cómo va la construcción del API? 28 | 29 | 30 | Y eso es justo. Probablemente si googleas algo relacionado con explorar un api, aparecerá una aplicación llamada https://www.getpostman.com/[Postman]. Este es un gran software pero no lo utilizaremos porque usaremos *cURL* que permite a cualquiera reproducir peticiones en cualquier computadora. 31 | 32 | == Configurar la API 33 | 34 | Una API es definida por http://en.wikipedia.org/wiki/Application_programming_interface[wikipedia] como _La interfaz de programación de aplicaciones (API), es un conjunto de subrutinas, funciones y procedimientos que ofrece cierta biblioteca para ser utilizado por otro software como una capa de abstracción. _ En otras palabras la forma en que el sistema interactúa entre sí mediante una interfaz común, en nuestro caso un servicio web construido con JSON. Hay otros protocolos de comunicación como SOAP, pero no lo cubriremos aquí. 35 | 36 | JSON, como tipo estándar en Internet, es ampliamente aceptado, legible, extensible y fácil de implementar. 37 | Muchos de los frameworks actuales consumen APIs JSON por defecto (https://angularjs.org/[Angular] ó https://vuejs.org/[Vue.js] por ejemplo). También hay grandes bibliotecas para Objetive-C como https://github.com/AFNetworking/AFNetworking[AFNetworking] ó http://restkit.org/[RESTKit]. Probablemente hay buenas soluciones para Android, pero por mi falta de experiencia en esa plataforma, podría no ser la persona adecuada para recomendarte alguna. 38 | 39 | Muy bien. Así que vamos a construir nuestra API con JSON. Hay muchos caminos para logarlo. Lo primero que me viene a la mente es justamente iniciar añadiendo rutas definiendo los _end points_. Pero puede ser mala idea porque no hay un http://www.w3.org/2005/Incubator/wcl/matching.html[patrón URI] suficientemente claro para saber que recurso está expuesto. El protocolo o estructura del que estoy hablando es http://en.wikipedia.org/wiki/Representational_state_transfer[REST] que significa Transferencia de Estado Representacional(Representational state transfer) según la definición de Wikipedia. 40 | 41 | [source,soap] 42 | ---- 43 | aService.getUser("1") 44 | ---- 45 | 46 | Y en REST puedes llamar una URL con una petición HTTP específica, en este caso con una petición GET: 47 | 48 | La APIs RESTful debe seguir al menos tres simples pautas: 49 | 50 | * Una base http://en.wikipedia.org/wiki/Uniform_resource_identifier[URI], como es `http://example.com/resources/`. 51 | * Un tipo multimedia de Internet para representar los datos, es comúnmente JSON y es comúnmente definido mediante el intercambio de cabeceras. 52 | * Sigue el estándar http://en.wikipedia.org/wiki/HTTP_method#Request_methods[Metodos HTTP] como son GET, POST, PUT, DELETE. 53 | ** *GET*: Lee el recurso o recursos definidos por el patrón URI 54 | ** *POST*: Crea una nueva entrada en la colección de recursos 55 | ** *PUT*: Actualiza una colección o un miembro de los recursos 56 | ** *DELETE*: Destruye una colección o miembro de los recursos 57 | 58 | Esto podría no ser suficientemente claro o podría parecer mucha información para digerir, pero como vamos avanzando en el tutorial, con suerte conseguirás entender con mayor facilidad. 59 | 60 | === Restricciones de Rutas y Espacios de Nombres 61 | 62 | Antes de comenzar a escribir código, preparamos el código con git. Vamos a estar usando una rama por capítulo, la subiremos a GitHub y entonces la fusionaremos con la rama master. Así que vamos a a iniciar abriendo la terminal, `cd` hacia el directorio `market_place_api` y tecleamos lo siguiente: 63 | 64 | [source,bash] 65 | ---- 66 | $ git checkout -b chapter02 67 | Switched to a new branch 'chapter02' 68 | ---- 69 | 70 | Únicamente vamos a estar trabajando en `config/routes.rb`, ya que solo vamos a establecer las restricciones y el `formato` de respuesta predeterminado para cada respuesta. 71 | 72 | [source,ruby] 73 | .config/routes.rb 74 | ---- 75 | Rails.application.routes.draw do 76 | # ... 77 | end 78 | ---- 79 | 80 | Primero que todo borra todo el código comentado que viene en el archivo, no lo vamos a necesitar. Entonces haz un commit, solo como un calentamiento: 81 | 82 | [source,bash] 83 | ---- 84 | $ git add config/routes.rb 85 | $ git commit -m "Removes comments from the routes file" 86 | ---- 87 | 88 | Vamos a aislar los controladores del API bajo un espacio de nombres. Con Rails esto es bastante simple: solo tienes que crear un folder en `app/controllers` llamado `api`. El nombre es importante porque es el espacio de nombres que usaremos para gestionar los controladores para los endpoints del api. 89 | 90 | [source,bash] 91 | ---- 92 | $ mkdir app/controllers/api 93 | ---- 94 | 95 | Entonces agregamos el nombre de espacio dentro de nuestro archivo _routes.rb_: 96 | 97 | [source,ruby] 98 | .config/routes.rb 99 | ---- 100 | Rails.application.routes.draw do 101 | # Api definition 102 | namespace :api do 103 | # We are going to list our resources here 104 | end 105 | end 106 | ---- 107 | 108 | Por definición un espacio de nombres en el archivo `routes.rb`. Rails automáticamente mapeara que espacio de nombres corresponde al folder de los _controlladores_, en nuestro caso el directorio `api/``. 109 | 110 | .Archivos multimedia soportados por Rails 111 | **** 112 | Rails soporta 35 tipos diferentes de archivos multimedia, puedes listarlos accediendo a la clase SET del módulo Mime: 113 | 114 | [source,bash] 115 | ---- 116 | $ rails c 117 | 2.6.3 :001 > Mime::SET.collect(&:to_s) 118 | => ["text/html", "text/plain", "text/javascript", "text/css", "text/calendar", "text/csv", "text/vcard", "text/vtt", "image/png", "image/jpeg", "image/gif", "image/bmp", "image/tiff", "image/svg+xml", "video/mpeg", "audio/mpeg", "audio/ogg", "audio/aac", "video/webm", "video/mp4", "font/otf", "font/ttf", "font/woff", "font/woff2", "application/xml", "application/rss+xml", "application/atom+xml", "application/x-yaml", "multipart/form-data", "application/x-www-form-urlencoded", "application/json", "application/pdf", "application/zip", "application/gzip"] 119 | ---- 120 | **** 121 | 122 | Esto es importante porque vamos a trabajar con JSON, uno de los http://en.wikipedia.org/wiki/Internet_media_type[tipos MIME] aceptados por Rails, solo necesitamos especificar que este es el formato por defecto: 123 | 124 | [source,ruby] 125 | .config/routes.rb 126 | ---- 127 | Rails.application.routes.draw do 128 | # Api definition 129 | namespace :api, defaults: { format: :json } do 130 | # We are going to list our resources here 131 | end 132 | end 133 | ---- 134 | 135 | Hasta este punto no hemos hecho nada loco. Ahora lo que queremos es una _base_uri_ que incluye la versión de la API. Pero hagamos commit antes de ir a la siguiente sección: 136 | 137 | [source,bash] 138 | ---- 139 | $ git add config/routes.rb 140 | $ git commit -m "Set the routes constraints for the api" 141 | ---- 142 | 143 | == Versionado Api 144 | 145 | Hasta este punto deberíamos tener un buen mapeado de rutas usando espacio de nombres. Tu archivo `routes.rb` debería lucir como esto: 146 | 147 | [source,ruby] 148 | .config/routes.rb 149 | ---- 150 | Rails.application.routes.draw do 151 | # Api definition 152 | namespace :api, defaults: { format: :json } do 153 | # We are going to list our resources here 154 | end 155 | end 156 | ---- 157 | 158 | Ahora es tiempo de configurar algunas otras restricciones para propósitos de versionado. Deberías preocuparte por versionar tú aplicación desde el inicio pues le dará una mejor estructura a tu api, y cuando hagas cambios, puedes dar a los desarrolladores que están consumiendo tu api la oportunidad de adaptar las nuevas características mientras las viejas quedan obsoletas. Este es un excelente http://railscasts.com/episodes/350-rest-api-versioning[railscast] explicando esto. 159 | 160 | Para establecer la versión del API, primero necesitamos agregar otro directorio en el de `api` que antes creamos: 161 | 162 | [source,bash] 163 | ---- 164 | $ mkdir app/controllers/api/v1 165 | ---- 166 | 167 | De esta forma podemos definir espacio de nombres a nuestra api con diferentes versiones fácilmente, ahora solo necesitamos añadir el código necesario al archivo `routes.rb`: 168 | 169 | [source,ruby] 170 | .config/routes.rb 171 | ---- 172 | Rails.application.routes.draw do 173 | # Api definition 174 | namespace :api, defaults: { format: :json } do 175 | namespace :v1 do 176 | # We are going to list our resources here 177 | end 178 | end 179 | end 180 | ---- 181 | 182 | Hasta este punto, el API puede ser alcanzada a través de la URL. Por ejemplo con esta configuración un end-point para recuperar un producto podría ser algo como: . 183 | 184 | 185 | .Patrones Comunes del API 186 | **** 187 | Puedes encontrar muchas formas de configurar un _base_uri_ cuando construimos un api siguiendo diferentes patrones, asumiendo que estamos versionando nuestra api: 188 | 189 | * `api.example.com/`: En mi opinión este es el camino a seguir, te da una mejor interfaz y aislamiento, y a largo plazo puede ayudarte a http://www.makeuseof.com/tag/optimize-your-dns-for-faster-internet/[escalar rápidamente] 190 | * `example.com/api/`: Este patrón es muy común, y es actualmente un buen camino a seguir cuando no quieres poner bajo espacio de nombres tu api en un subdominio 191 | * `example.com/api/v1`: parece buena idea, poniendo la versión del api mediante la URL, parece como un patrón descriptivo, pero esta forma te forza a incluir la URL en cada petición, así que si en algún momento decides cambiar este patrón, se convierte en un problema de mantenimiento a largo plazo. 192 | 193 | Estas son algunas prácticas en la construcción de una API que recomiendan no versionar el API a través de la URL. Es verdad. El desarrollador no debería conocer la versión que está usando. En términos de simplicidad, he decidido dejar esta convención, que podremos aplicar en una segunda fase. 194 | **** 195 | 196 | Es tiempo de hacer _commit_: 197 | 198 | [source,bash] 199 | ---- 200 | $ git commit -am "Set the versioning namespaces for API" 201 | ---- 202 | 203 | Estamos en lo último del capítulo. Por lo tanto, es tiempo de aplicar nuestras modificaciones a la rama master haciendo un _merge_. Para hacerlo, nos cambiamos a la rama `master` y hacemos _merge_ de `chapter02`: 204 | 205 | [source,bash] 206 | ---- 207 | $ git checkout master 208 | $ git merge chapter02 209 | ---- 210 | 211 | == Conclusión 212 | 213 | Ha sido un largo camino, lo sé, pero lo hiciste, no te rindas esto solo es un pequeño escalón para cualquier cosa grande, así que sigue. Mientras tanto y si te sientes curioso hay algunas gemas que pueden manejar este tipo de configuración: 214 | 215 | * https://github.com/Sutto/rocket_pants[RocketPants] 216 | * https://github.com/bploetz/versionist[Versionist] 217 | 218 | No cubriré eso en este libro, ya que estamos intentando aprender a implementar este tipo de funcionalidades, pero es bueno saberlo. Por cierto, el código hasta este punto está https://github.com/madeindjs/market_place_api_6/releases/tag/checkpoint_chapter03[aquí]. 219 | -------------------------------------------------------------------------------- /rails6/fr/chapter02-api.adoc: -------------------------------------------------------------------------------- 1 | [#chapter02-api] 2 | = L'API 3 | 4 | Dans ce chapitre, je vais vous donner les grandes lignes de l'application. Vous devriez avoir lu le chapitre précédent. Si ce n'est pas le cas, je vous recommande de le faire. 5 | 6 | Vous pouvez cloner le projet jusqu'ici avec: 7 | 8 | [source,bash] 9 | ---- 10 | $ git checkout tags/checkpoint_chapter02 11 | ---- 12 | 13 | Pour résumer, nous avons simplement généré notre application Rails et réalisé notre premier commit. 14 | 15 | 16 | == Planification de l'application 17 | 18 | Notre application sera assez simple. Elle se composera de cinq modèles. Ne vous inquiétez pas si vous ne comprenez pas bien ce qui se passe, nous reverrons et développerons chacune de ces ressources au fur et à mesure que nous avancerons avec le tutoriel. 19 | 20 | ---- 21 | +---------+ +---------+ 22 | | User +---->+Product | 23 | +---------+ +---------+ 24 | | | 25 | v v 26 | +---------+ +---------+ 27 | |Order +---->+Placement| 28 | +---------+ +---------+ 29 | ---- 30 | 31 | En bref, nous avons l’utilisateur (`User`) qui sera en mesure de créer des commandes (`Order`). Il pourra aussi passer de nombreuses commandes (`Order`) qui vont contenir des éléments (`Placement`) qui désignes des produits. 32 | 33 | Nous n'allons pas construire d'interface pour l'interaction avec l'API afin de ne pas surcharger le tutoriel. Si vous voulez construire des vues, il existe de nombreuses options comme des frameworks JavaScript (https://angularjs.org/[Angular], https://vuejs.org/[Vue.JS], https://reactjs.org/[React]) ou des librairies mobiles (https://github.com/AFNetworking/AFNetworking[AFNetworking]). 34 | 35 | À ce stade, vous devriez vous poser cette question: 36 | 37 | > D'accord, mais j'ai besoin d'explorer et de visualiser l'API que je vais construire, non? 38 | 39 | C'est juste. Si vous _googlez_ quelque chose lié à l'exploration d'une API, vous allez trouver pas mal de résultats. Vous pouvez par exemple utiliser https://www.getpostman.com/[Postman] qui est devenu incontournable. Mais nous n'allons pas l'utiliser. Dans notre cas nous allons utiliser *cURL* qui est un outil en ligne de commande disponible presque partout. 40 | 41 | == Mettre en place l'API 42 | 43 | Une API est définie par https://fr.wikipedia.org/wiki/Interface_de_programmation[wikipedia] comme _une interface de programmation d'application (API) qui est un ensemble normalisé de composants qui sert de façade par laquelle un logiciel offre des services à d'autres logiciels_. En d'autres termes, il s'agit d'une façon dont les systèmes interagissent les uns avec les autres via une interface (dans notre cas un service web construit avec JSON). Il existe d'autres types de protocoles de communication comme SOAP, mais nous n'en parlons pas ici. 44 | 45 | JSON est devenu incontournable en tant que format de fichier pour Internet en raison de sa lisibilité, de son extensibilité et de sa facilité à mettre en œuvre. Beaucoup de frameworks JavaScript l'utilisent comme protocole par défaut comme https://angularjs.org/[Angular] ou http://emberjs.com/[EmberJS]. D'autres grandes bibliothèques en Objective-C l'utilisent comme https://github.com/AFNetworking/AFNetworking[AFNetworking] ou http://restkit.org/[RESTKit]. Il existe probablement de bonnes solutions pour Android mais en raison de mon manque d'expérience sur cette plate-forme de développement je ne peux pas vous recommander quelque chose. 46 | 47 | Nous allons donc utiliser le format JSON pour construire notre API. La première idée qui pourrait vous venir à l'esprit serait de commencer à créer des routes en vrac. Le problème est qu'elles ne seraient pas normalisées. Un utilisateur ne pourrait pas deviner quelle ressource est renvoyée par une route. 48 | 49 | C'est pourquoi une norme existe: *REST* _(Representational State Transfer)_. REST impose une norme pour les routes qui créent, lisent, mettent à jour ou suppriment des informations sur un serveur en utilisant de simples appels HTTP. C'est une alternative aux mécanismes plus complexes comme SOAP, CORBA et RPC. Un appel REST est simplement une requête GET HTTP vers le serveur. 50 | 51 | [source,soap] 52 | ---- 53 | aService.getUser("1") 54 | ---- 55 | 56 | Et avec REST, vous pouvez appeler une URL avec une requête HTTP spécifique. Dans ce cas avec une requête GET: 57 | 58 | .... 59 | http://domain.com/resources_name/uri_pattern 60 | .... 61 | 62 | Les API _RESTful_ doivent suivre au minimum trois règles: 63 | 64 | * Une URI de base comme http://example.com/resources/ 65 | * Un type de média Internet pour représenter les données, il est communément JSON et est communément défini par l'échange d'en-têtes. 66 | * Suivez les méthodes https://fr.wikipedia.org/wiki/Hypertext_Transfer_Protocol[HTTP] standard telles que GET, POST, PUT, PUT, DELETE. 67 | ** *GET*: Lit la ou les ressources définies par le modèle URI 68 | ** *POST*: Crée une nouvelle entrée dans la collection de ressources 69 | ** *PUT*: Met à jour une collection ou un membre des ressources 70 | ** *DELETE*: Détruit une collection ou un membre des ressources 71 | 72 | Cela peut sembler compliqué mais au fur et à mesure que nous avancerons dans le tutoriel cela deviendra beaucoup plus facile à comprendre. 73 | 74 | === Routes, contraintes et _Namespaces_ 75 | 76 | Avant de commencer à taper du code, nous allons préparer le répertoire Git. Le _workflow_ que nous allons suivre est le suivant: 77 | 78 | * Nous allons créer une branche par chapitre 79 | * Une fois terminé, nous pousserons la branche sur GitHub 80 | * Nous la fusionnerons avec master 81 | 82 | Commençons donc par ouvrir le terminal dans le répertoire `market_place_api` et tapez la commande suivante pour créer la branche: 83 | 84 | [source,bash] 85 | ---- 86 | $ git checkout -b chapter02 87 | Switched to a new branch 'chapter02' 88 | ---- 89 | 90 | Nous allons seulement travailler sur le fichier `config/routes.rb` car nous allons simplement définir les contraintes et le format de réponse par défaut pour chaque requête. 91 | 92 | [source,ruby] 93 | .config/routes.rb 94 | ---- 95 | Rails.application.routes.draw do 96 | # ... 97 | end 98 | ---- 99 | 100 | Effacez tout le code commenté qui se trouve dans le fichier. Nous n'en aurons pas besoin. Ensuite, faites un _commit_, juste pour vous échauffer: 101 | 102 | [source,bash] 103 | ---- 104 | $ git commit -am "Removes comments from the routes file" 105 | ---- 106 | 107 | Nous allons isoler les contrôleurs API dans des _Namespace_. Avec Rails, c'est assez simple. Il suffit de créer un dossier sous `app/controllers` nommé `api`. Le nom est important car c'est le _Namespace_ que nous allons utiliser pour gérer les contrôleurs pour les points d'entrée de l'API 108 | 109 | [source,bash] 110 | ---- 111 | $ mkdir app/controllers/api 112 | ---- 113 | 114 | Nous ajoutons ensuite ce _Namespace_ dans notre fichier `routes.rb`: 115 | 116 | [source,ruby] 117 | .config/routes.rb 118 | ---- 119 | Rails.application.routes.draw do 120 | # Api definition 121 | namespace :api do 122 | # We are going to list our resources here 123 | end 124 | end 125 | ---- 126 | 127 | En définissant un _Namespace_ dans le fichier `routes.rb`, Rails mappera automatiquement ce _Namespace_ à un répertoire correspondant au nom sous le dossier contrôleur (dans notre cas le répertoire `api/`). 128 | 129 | .Les types de medias supportés par Rails 130 | **** 131 | Rails supporte jusqu'à 35 types de médias différents! Vous pouvez les lister en accédant à la classe `SET` sous le module de `Mime`: 132 | 133 | [source,bash] 134 | ---- 135 | $ rails c 136 | 2.6.3 :001 > Mime::SET.collect(&:to_s) 137 | => ["text/html", "text/plain", "text/javascript", "text/css", "text/calendar", "text/csv", "text/vcard", "text/vtt", "image/png", "image/jpeg", "image/gif", "image/bmp", "image/tiff", "image/svg+xml", "video/mpeg", "audio/mpeg", "audio/ogg", "audio/aac", "video/webm", "video/mp4", "font/otf", "font/ttf", "font/woff", "font/woff2", "application/xml", "application/rss+xml", "application/atom+xml", "application/x-yaml", "multipart/form-data", "application/x-www-form-urlencoded", "application/json", "application/pdf", "application/zip", "application/gzip"] 138 | ---- 139 | **** 140 | 141 | C'est important parce que nous allons travailler avec JSON, l'un des types MIME intégrés par Rails. Ainsi nous avons juste besoin de spécifier ce format comme format par défaut: 142 | 143 | [source,ruby] 144 | .config/routes.rb 145 | ---- 146 | Rails.application.routes.draw do 147 | # Api definition 148 | namespace :api, defaults: { format: :json } do 149 | # We are going to list our resources here 150 | end 151 | end 152 | ---- 153 | 154 | Jusqu'à présent, nous n'avons rien fait de fou. Nous voulons maintenant générer un _base_uri_ qui inclut la version de l'API comme ceci: http://localhost:3000/api/v1. 155 | 156 | NOTE: Régler l'API sous un sous-domaine est une bonne pratique car cela permet d'adapter l'application à un niveau DNS. Mais dans notre cas, nous allons simplifier les choses pour l'instant. 157 | 158 | Vous devriez vous soucier de versionner votre application dès le début car cela donnera une *meilleure structure* à votre API. Lorsque des changements interviendront sur votre API, vous pouvez ainsi proposer aux développeurs de s'adapter aux nouvelles fonctionnalités pendant que les anciennes sont dépréciées. 159 | 160 | [source,ruby] 161 | .config/routes.rb 162 | ---- 163 | Rails.application.routes.draw do 164 | namespace :api, defaults: { format: :json } do 165 | namespace :v1 do 166 | # We are going to list our resources here 167 | end 168 | end 169 | end 170 | ---- 171 | 172 | .Les conventions des API 173 | **** 174 | Vous pouvez trouver de nombreuses approches pour configurer la `base_uri` d'une API. En supposant que nous versionnons notre api: 175 | 176 | * `api.example.com/`: Je suis d'avis que c'est la voie à suivre, elle vous donne une meilleure interface et l'isolement, et à long terme peut vous aider à http://www.makeuseof.com/tag/optimize-your-dns-for-faster-internet/[mettre rapidement à l'échelle] 177 | * `example.com/api/`: Ce modèle est très commun. C'est un bon moyen de commencer quand vous ne voulez pas de _Namespace_ de votre API avec sous un sous-domaine 178 | * `example.com/api/v1`: Cela semble être une bonne idée. Définir la version de l'API par l'URL semble être un modèle plus descriptif. Cependant, vous forcez à inclure la version à l'URL sur chaque demande. Cela devient un problème si vous décidez de changer ce modèle 179 | **** 180 | 181 | Il est temps de faire un _commit_: 182 | 183 | [source,bash] 184 | ---- 185 | $ git add config/routes.rb 186 | $ git commit -m "Set the routes constraints for the api" 187 | ---- 188 | 189 | Afin de définir la version de l'API, nous devons d'abord ajouter un autre répertoire sous le dossier `api/` que nous avons créé: 190 | 191 | [source,bash] 192 | ---- 193 | $ mkdir app/controllers/api/v1 194 | ---- 195 | 196 | L'API est désormais _scopée_ via l'URL. Par exemple, avec la configuration actuelle, la récupération d'un produit via l'API se ferait avec cette url: http://localhost:3000/v1/products/1. 197 | 198 | Ne vous inquiétez pas, nous rentrerons plus en détails à propos du versionnement plus tard. Il est temps de _commiter_: 199 | 200 | [source,bash] 201 | ---- 202 | $ git commit -am "Set the routes namespaces for the api" 203 | ---- 204 | 205 | NOTE: Il existe certaines pratiques dans la construction d'API qui recommandent de ne pas versionner l'API via l'URL. C'est vrai. Le développeur ne devrait pas être au courant de la version qu'il utilise. Dans un souci de simplicité, j'ai choisi de mettre de côté cette convention que nous pourrons appliquer dans un second temps. 206 | 207 | Nous arrivons à la fin de notre chapitre. Il est donc temps d'appliquer toutes nos modifications sur la branche master en faisant un _merge_. Pour cela, on se place sur la branche `master` et on _merge_ `chapter02`: 208 | 209 | [source,bash] 210 | ---- 211 | $ git checkout master 212 | $ git merge chapter02 213 | ---- 214 | 215 | 216 | == Conclusion 217 | 218 | Ça a été un peu long, je sais, mais vous avez réussi! N'abandonnez pas, c'est juste notre petite fondation pour quelque chose de grand, alors continuez comme ça. Sachez qu'il y a des gemmes qui gèrent ce genre de configuration pour nous: 219 | 220 | * https://github.com/Sutto/rocket_pants[RocketPants] 221 | * https://github.com/bploetz/versionist[Versionist] 222 | 223 | Je n'en parle pas ici puisque nous essayons d'apprendre comment mettre en œuvre ce genre de fonctionnalité. 224 | -------------------------------------------------------------------------------- /rails6/es/chapter01-introduction.adoc: -------------------------------------------------------------------------------- 1 | [#chapter01-introduction] 2 | = Introducción 3 | 4 | Bienvenido a API on Rails 6, un tutorial con esteroides para enseñarte el mejor camino para construir tú siguiente API con Rails. El propósito de este libro es proveer una metodología comprensiva para desarrollar una API RESTful siguiendo las mejores prácticas. 5 | 6 | Al finalizar este libro, tu podrás crear tu propia API e integrarla con cualquier cliente como un navegador web o aplicación móvil. El código generado esta codeado con Ruby on Rails 6.0 que es la versión actual. 7 | 8 | El propósito de este libro no es solamente enseñarte como construir un API con Rails sino mucho mejor enseñarte como construir una API *evolutiva* y *mantenible* con Rails. Esto es, mejorar tu conocimiento actual con Rails. En esta sección, aprenderás a: 9 | 10 | - Usar Git para control de versiones 11 | - Construir respuestas JSON 12 | - Probar tus end-points con pruebas unitarias y funcionales 13 | - Configurar autenticación con JSON Web Tokens (JWT) 14 | - Usar la especificación JSON:API 15 | - Optimizar y hacer cache de la API 16 | 17 | Recomiendo enérgicamente que sigas todos los pasos en este libro. Intenta no saltarte capítulos porque doy algunos tips y trucos para improvisar tus habilidades a través del libro. Puedes considerarte a ti mismo el personaje principal de un videojuego que gana un nivel en cada capítulo. 18 | 19 | 20 | En este primer capítulo explicaré como configurar tu entorno de desarrollo (en caso que aún no lo sepas). Luego vamos a crear una aplicación llamada `market_place_api`. Me aseguraré que te enseño las mejores practicas que he aprendido durante mi experiencia. Esto significa que vamos a iniciar usando *Git* justo después de inicializar el proyecto. 21 | 22 | Vamos a crear la aplicación siguiendo un método simple de trabajo que usé a diario en los siguientes capítulos. Vamos a desarrollar una aplicación completa usando Test Driven Development(TDD). También explicaré el interés de usar una API para tu siguiente proyecto y eligiendo un adecuado formato de respuesta como JSON o XML. Mas allá, vamos a tener nuestras manos sobre el código y completar lo básico de la aplicación construyendo todos los caminos necesarios. También vamos a implementar acceso seguro a la API implementando autenticación por intercambio de cabeceras HTTP. Finalmente, en el último capítulo, vamos a añadir técnicas de optimización para mejorar la estructura y tiempos de respuesta del servidor. 23 | 24 | La aplicación final rozará la superficie de iniciar una tienda donde los usuario pueden realizar ordenes, subir productos y más. Hay muchas opciones allá afuera para echar a andar una tienda en linea, como http://shopify.com[Shopify], http://spreecommerce.com/[Spree] o http://magento.com[Magento]. 25 | 26 | 27 | == Convenciones en este libro 28 | 29 | Las convenciones en este libro están basadas en este http://www.railstutorial.org/book/beginning#sec-conventions[Tutorial de Ruby on Rails]. En esta sección vamos a mencionar algunas que tal vez no son muy claras. 30 | 31 | Utilizaré muchos ejemplos usando la línea de comandos. No intentare con windows `cmd` (lo siento chic@s), así que basare todos los ejemplos usando el estilo Unix, como a continuación se observa: 32 | 33 | [source,bash] 34 | ---- 35 | $ echo "A command-line command" 36 | A command-line command 37 | ---- 38 | 39 | Estaré usando algunas pautas relacionadas al lenguaje, y me refiero a lo siguiente: 40 | 41 | * *Evitar* significa que no debes hacerlo 42 | * *Preferir* indica que las 2 opciones, la primera es mejor 43 | * *Usar* significa que eres bueno para usar el recurso 44 | 45 | 46 | Si por alguna razón encuentras errores cuando ejecutas un comando, en lugar de tratar de explicar cada resultado posible, te recomiendo 'googlearlo', lo cual no lo considero una mala práctica. Pero si te gusta tomar una cerveza o tienes problemas con el tutorial siempre puedes mailto:contact@rousseau-alexandre.fr[escribirme]. 47 | 48 | == Entornos de desarrollo 49 | 50 | Una de las partes más dolorosas para casi todo desarrollador es configurar el entorno de desarrollo, pero mientras lo hagas, los siguientes pasos pueden ser una pieza del pastel y una buena recompensa. Así que voy a guiarte para que te sientas motivado. 51 | 52 | === Editores de texto y terminal 53 | 54 | Hay muchos casos en que los entornos de desarrollo pueden diferir de computadora a computadora. Este no es el caso con los editores de texto o IDE's. Pienso que para el desarrollo en Rails un IDE es demasiado, pero alguien podría encontrarlo como la mejor forma de hacerlo, así que si es tú caso te recomiendo que lo hagas con http://www.aptana.com/products/radrails[RadRails] o http://www.jetbrains.com/ruby/index.html[RubyMine], ambos están bien soportados y vienen con muchas integraciones 'out of the box'. 55 | 56 | *Editor de texto*: En lo personal uso http://www.vim.org/[vim] como mi editor por defecto con https://github.com/carlhuda/janus[janus] el cual puede añadir y manejar muchos de los plugins que probablemente vas a utilizar. En caso que no sea un fan de _vim_ como yo, hay muchas otras soluciones como http://www.sublimetext.com/[Sublime Text] que es multi plataforma, fácil de aprender y personalizable (este es probablemente tú mejor opción), esta altamente inspirado por http://macromates.com/[TextMate] (solo disponible para Mac OS). Una tercera opción es usando un muy reciente editor de texto de los chicos de http://gitub.com[GitHub] llamado https://atom.io/[Atom], es un prometedor editor de texto echo con JavaScript, es fácil de extender y personalizar para satisfacer tus necesidades, dale una oportunidad. Cualquiera de los editores que te presento harán del trabajo, así que te dejo elegir cual se ajusta a tu ojo. 57 | 58 | *Terminal*: Si decides seguir con http://icalialabs.github.io/kaishi/[kaishi] para configurar el entorno, notarás que pone pro defecto el shell con `zsh`, lo cual recomiendo bastante. Para la terminal, no soy fan de aplicaciones de _Terminal_ que traen mejoras si estas en Mac OS, así que mira http://www.iterm2.com/#/section/home[iTerm2], Que es un remplazo de la terminal para Mac OS. Si estas en Linux probablemente ya tienes una linda terminal, pero la que viene por defecto puede funcionar bien. 59 | 60 | === Navegadores 61 | 62 | Cuando se trata de navegadores diría http://www.mozilla.org/en-US/firefox/new/[Firefox] inmediatamente, pero algunos otros desarrolladores pueden decir https://www.google.com/intl/en/chrome/browser/[Chrome] o incluso https://www.apple.com/safari/[Safari]. Cualquiera de ellos ayudara a construir la aplicación que buscas, ellos vienen con un buen inspector no justamente para el DOM pero para el análisis de red y muchas otras características que ya conoces. 63 | 64 | === Manejador de paquetes 65 | 66 | * *Mac OS*: Hay muchas opciones para gestionar o instalar tus paquetes en tu Mac, como el https://www.macports.org/[Mac Ports] ó http://brew.sh/[Homebrew], ambos son buenas opciones pero yo elegiría la última, he encontrado menos problemas cuando instalo software y lo administro. Para instalar `brew` solo ejecuta en la consola lo siguiente: 67 | 68 | [source,bash] 69 | ---- 70 | $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 71 | ---- 72 | 73 | * *Linux*: Estas listo!, realmente no es mucho problema si tu estas usando `apt`, `pacman`, `yum` siempre que te sientas cómodo con ello sepas como instalar paquetes para poder seguir avanzando. 74 | 75 | === Git 76 | 77 | Usaremos Git bastante, y puedes usarlo no solo para el propósito de este tutorial sino para cada proyecto independiente. 78 | 79 | * en Mac OS: `$ brew install git` 80 | * en Linux: `$ sudo apt-get install git` 81 | 82 | === Ruby 83 | 84 | Son muchos los caminos en que puedes instalar y gestionar ruby, y ahora tú puedes tener probablemente alguna versión instalada si estas en Mac OS, para ver la versión que tienes, solo ejecuta: 85 | 86 | [source,bash] 87 | ---- 88 | $ ruby -v 89 | ---- 90 | 91 | Rails 6.0 requiere la instalación de la versión 2.5 o mayor. 92 | 93 | Yo recomiendo usar http://rvm.io/[Ruby Version Manager (RVM)] ó http://rbenv.org/[rbenv] para instalarlo. Vamos a usar RVM en este tutorial, pero no hay problema con cuál de las 2 utilices. 94 | 95 | El principio de esta herramienta es permitirte instalar varias versiones de Ruby en el mismo equipo, en un entorno hermético con una posible versión instalada en tu sistema operativo y luego tener la habilidad de cambiar de una a otra versión fácilmente. 96 | 97 | Para instalar RVM, ve a https://rvm.io/ e instala la huella de la llave GPG: [La huella de la llave GPG te permite verificar la identidad del autor o del origen de la descarga.]. Para realizarlo ejecutamos: 98 | 99 | [source,bash] 100 | ---- 101 | $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB 102 | $ \curl -sSL https://get.rvm.io | bash 103 | ---- 104 | 105 | Ahora instalaremos ruby: 106 | 107 | [source,bash] 108 | ---- 109 | $ rvm install 2.6 110 | ---- 111 | 112 | Ahora es momento de instalar el resto de dependencias que vamos a usar. 113 | 114 | ==== Gemas, Rails y Librerías faltantes 115 | 116 | 117 | Primero actualizamos las gemas en el sistema: 118 | 119 | [source,bash] 120 | ---- 121 | $ gem update --system 122 | ---- 123 | 124 | En algunos casos si estas en Mac OS, necesitarás instalar algunas librerías extras: 125 | 126 | [source,bash] 127 | ---- 128 | $ brew install libtool libxslt libksba openssl 129 | ---- 130 | 131 | Luego instalamos las gemas necesarias e ignoramos la documentación para cada una: 132 | 133 | [source,bash] 134 | ---- 135 | $ gem install bundler 136 | $ gem install rails -v 6.0.0 137 | ---- 138 | 139 | Revisamos que todo funciona correctamente: 140 | 141 | [source,bash] 142 | ---- 143 | $ rails -v 144 | Rails 6.0.0 145 | ---- 146 | 147 | ==== Base de datos 148 | 149 | Recomiendo mucho que instales http://www.postgresql.org/[Postgresql] para gestionar tus bases de datos. Pero aquí usaremos http://www.sqlite.org/[SQlite] por simplicidad. Si estas usando Mac OS estas listo para continuar, en caso que uses Linux, no te preocupes solo nos faltan unos pasos más: 150 | 151 | [source,bash] 152 | ---- 153 | $ sudo apt-get install libxslt-dev libxml2-dev libsqlite3-dev 154 | ---- 155 | 156 | ó 157 | 158 | [source,bash] 159 | ---- 160 | $ sudo yum install libxslt-devel libxml2-devel libsqlite3-devel 161 | ---- 162 | 163 | == Inicializando el proyecto 164 | 165 | Inicializar una aplicación Rails puede ser muy sencillo para ti. Si no es el caso aquí tienes un tutorial super rápido. 166 | 167 | Estos son los comandos: 168 | 169 | [source,bash] 170 | ---- 171 | $ mkdir ~/workspace 172 | $ cd ~/workspace 173 | $ rails new market_place_api --api 174 | ---- 175 | 176 | NOTE: La opción `--api` apareció en la versión 5 de Rails. Ésta te permite limitar las librerías y _Middleware_ incluido en la aplicación. Esto también evita generar vistas HTML cuando se usan los generadores de Rails. 177 | 178 | Como puedes adivinar, los anteriores comandos generaran los huesos desnudos de tu aplicación Rails. 179 | 180 | == Versionado 181 | 182 | Recuerda que Git te ayuda a dar seguimiento y mantener el historial de tu código. Ten en mente que el codigo fuente de la aplicación es publicado en GitHub. Puedes seguir el proyecto en https://github.com/madeindjs/market_place_api_6[GitHub]. 183 | 184 | Ruby on Rails inicializa el directorio Git por tí cuando usas el comando `rails new`. Esto significa que no necesitas ejecutar el comando `git init`. 185 | 186 | Sin embargo es necesario configurar la información del autor de los _commits_. Si aún no lo has echo, ve al directorio de proyecto y corre los siguientes comandos: 187 | 188 | [source,bash] 189 | ---- 190 | $ git config --global user.name "Aquí pon tu nombre" 191 | $ git config --global user.email "Aquí pon tu email" 192 | ---- 193 | 194 | Rails también provee un archivo `.gitignore` para ignorar algunos archivos a los que no queramos dar seguimiento. El archivo `.gitignore` por defecto puede lucir como se ve a continuación: 195 | 196 | ..gitignore 197 | ---- 198 | # Ignore bundler config. 199 | /.bundle 200 | 201 | # Ignore the default SQLite database. 202 | /db/*.sqlite3 203 | /db/*.sqlite3-journal 204 | 205 | # Ignore all logfiles and tempfiles. 206 | /log/* 207 | /tmp/* 208 | !/log/.keep 209 | !/tmp/.keep 210 | 211 | # Ignore uploaded files in development. 212 | /storage/* 213 | !/storage/.keep 214 | .byebug_history 215 | 216 | # Ignore master key for decrypting credentials and more. 217 | /config/master.key 218 | ---- 219 | 220 | Después de modificar el archivo `.gitignore` únicamente necesitamos añadir los archivos y hacer _commit_ de los cambios, para ello usamos los siguientes comandos: 221 | 222 | [source,bash] 223 | ---- 224 | $ git add . 225 | $ git commit -m "Commit Inicial" 226 | ---- 227 | 228 | TIP: He encontrado que el mensaje del commit debería iniciar con un verbo en tiempo presente, describiendo lo que el commit hace y no lo que hizo, ayuda cuando estás explorando el historial del proyecto. Encontré esto más natural para leer y entender. Seguiremos esta práctica hasta el final del tutorial. 229 | 230 | Por ultimo y como un paso opcional configuramos el proyecto en GitHub y hacemos _push_ de nuestro código al servidor remoto: Pero primero añadimos el _remoto_: 231 | 232 | [source,bash] 233 | ---- 234 | $ git remote add origin git@github.com:madeindjs/market_place_api_6.git 235 | ---- 236 | 237 | Entonces hacemos _push_(empujamos) el código: 238 | 239 | [source,bash] 240 | ---- 241 | $ git push -u origin master 242 | ---- 243 | 244 | A medida que avanzamos con el tútorial, usaré las practicas que uso a diario, esto incluye trabajar con `branches`(ramas), `rebasing`, `squash` y algo mas. Por ahora no debes preocuparte si algunos términos no te suenan familiares, te guiaré en ello con el tiempo. 245 | 246 | == Conclusión 247 | 248 | Ha sido un largo camino a través de este capítulo, si has llegado hasta aquí déjame felicitarte y asegurarte que a partir de este punto las cosas mejorarán. Asi que vamos a ensuciarnos las manos y comenzar a escribir algo de código! 249 | -------------------------------------------------------------------------------- /rails5/en/chapter04-refactoring-tests.adoc: -------------------------------------------------------------------------------- 1 | [#chapter04-refactoring-tests] 2 | = Refactoring tests 3 | 4 | In previous chapter we manage to put together some `user` resources endpoints. If you skip it (or simple missed it) I highly recommend you take a look at it. It covers the first test specs and an introduction to JSON responses. 5 | 6 | You can clone the project until this point with: 7 | 8 | [source,bash] 9 | ---- 10 | $ git clone --branch chapitre_3 https://github.com/madeindjs/market_place_api 11 | ---- 12 | 13 | In this chapter we'll refactor our test specs by adding some helper methods. We'll also remove the `format` param sent on every request and do it through headers. Also we hopefully build more consistent and scalable test suite. 14 | 15 | So let' take a look to the `users_controller_spec.rb` file: 16 | 17 | [source,ruby] 18 | .spec/controllers/api/v1/users_controller_spec.rb 19 | ---- 20 | # ... 21 | RSpec.describe Api::V1::UsersController, type: :controller do 22 | before(:each) { request.headers['Accept'] = 'application/vnd.marketplace.v1' } 23 | 24 | describe 'GET #show' do 25 | before(:each) do 26 | @user = FactoryBot.create :user 27 | get :show, params: { id: @user.id, format: :json } 28 | end 29 | 30 | it 'returns the information about a reporter on a hash' do 31 | user_response = JSON.parse(response.body, symbolize_names: true) 32 | expect(user_response[:email]).to eql @user.email 33 | end 34 | 35 | it { expect(response.response_code).to eq(200) } 36 | end 37 | 38 | describe 'POST #create' do 39 | context 'when is successfully created' do 40 | before(:each) do 41 | @user_attributes = FactoryBot.attributes_for :user 42 | post :create, params: { user: @user_attributes }, format: :json 43 | end 44 | 45 | it 'renders the json representation for the user record just created' do 46 | user_response = JSON.parse(response.body, symbolize_names: true) 47 | expect(user_response[:email]).to eql @user_attributes[:email] 48 | end 49 | 50 | it { expect(response.response_code).to eq(201) } 51 | end 52 | 53 | context 'when is not created' do 54 | before(:each) do 55 | # notice I'm not including the email 56 | @invalid_user_attributes = { password: '12345678', 57 | password_confirmation: '12345678' } 58 | post :create, params: { user: @invalid_user_attributes }, format: :json 59 | end 60 | 61 | it 'renders an errors json' do 62 | user_response = JSON.parse(response.body, symbolize_names: true) 63 | expect(user_response).to have_key(:errors) 64 | end 65 | 66 | it 'renders the json errors on why the user could not be created' do 67 | user_response = JSON.parse(response.body, symbolize_names: true) 68 | expect(user_response[:errors][:email]).to include "can't be blank" 69 | end 70 | 71 | it { expect(response.response_code).to eq(422) } 72 | end 73 | end 74 | 75 | describe "PUT/PATCH #update" do 76 | 77 | context "when is successfully updated" do 78 | before(:each) do 79 | @user = FactoryBot.create :user 80 | patch :update, params: { 81 | id: @user.id, 82 | user: { email: "newmail@example.com" } }, 83 | format: :json 84 | end 85 | 86 | it "renders the json representation for the updated user" do 87 | user_response = JSON.parse(response.body, symbolize_names: true) 88 | expect(user_response[:email]).to eql "newmail@example.com" 89 | end 90 | 91 | it { expect(response.response_code).to eq(200) } 92 | end 93 | 94 | context "when is not created" do 95 | before(:each) do 96 | @user = FactoryBot.create :user 97 | patch :update, params: { 98 | id: @user.id, 99 | user: { email: "bademail.com" } }, 100 | format: :json 101 | end 102 | 103 | it "renders an errors json" do 104 | user_response = JSON.parse(response.body, symbolize_names: true) 105 | expect(user_response).to have_key(:errors) 106 | end 107 | 108 | it "renders the json errors on why the user could not be created" do 109 | user_response = JSON.parse(response.body, symbolize_names: true) 110 | expect(user_response[:errors][:email]).to include "is invalid" 111 | end 112 | 113 | it { expect(response.response_code).to eq(422) } 114 | end 115 | end 116 | 117 | describe "DELETE #destroy" do 118 | before(:each) do 119 | @user = FactoryBot.create :user 120 | delete :destroy, params: { id: @user.id }, format: :json 121 | end 122 | 123 | it { expect(response.response_code).to eq(204) } 124 | end 125 | end 126 | ---- 127 | 128 | As you can see there is a lot of duplicated code, two big refactors here are: 129 | 130 | * The `JSON.parse` method can be encapsulated on a method. 131 | * The `format` param is sent on every request. Although is not a bad practice but it is better if you handle the response type through headers. 132 | 133 | So let's add a method for handling the JSON response. If you have been following the tutorial you may know that we are creating a branch for each chapter. So let's do that: 134 | 135 | [source,bash] 136 | ---- 137 | $ git checkout -b chapter4 138 | ---- 139 | 140 | == Refactoring the JSON response 141 | 142 | Back to the `refactor`, we will add file under the `spec/support` directory. Currently we don't have this directory. So let's add it: 143 | 144 | [source,bash] 145 | ---- 146 | $ mkdir spec/support 147 | ---- 148 | 149 | Then we create a `request_helpers.rb` file under the just created `support` directory: 150 | 151 | [source,bash] 152 | ---- 153 | $ touch spec/support/request_helpers.rb 154 | ---- 155 | 156 | It is time to extract the `JSON.parse` method into our own support method: 157 | 158 | [source,ruby] 159 | .spec/support/request_helpers.rb 160 | ---- 161 | module Request 162 | module JsonHelpers 163 | def json_response 164 | @json_response ||= JSON.parse(response.body, symbolize_names: true) 165 | end 166 | end 167 | end 168 | ---- 169 | 170 | We scope the method into some `modules` just to keep our code nice and organized. The next step here is to update the `users_controller_spec.rb` file to use the method. A quick example is presented below: 171 | 172 | [source,ruby] 173 | .spec/controllers/api/v1/users_controller_spec.rb 174 | ---- 175 | # ... 176 | it 'returns the information about a reporter on a hash' do 177 | user_response = json_response # c'est cette ligne qui est maj 178 | expect(user_response[:email]).to eql @user.email 179 | end 180 | # ... 181 | ---- 182 | 183 | Now it is your turn to update the whole file. 184 | 185 | After you are done updating the file and if you tried to run your tests you probably encounter a problem. For some reason it is not finding the `json_response` method which is weird because if we take a look at the `spec_helper.rb` file. We can see that is actually loading all files from the `support` directory: 186 | 187 | [source,ruby] 188 | .spec/rails_helper.rb 189 | ---- 190 | # Load all Ruby files placed in spec/support folder 191 | Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each do |f| 192 | require f 193 | end 194 | 195 | RSpec.configure do |config| 196 | # ... 197 | # We also need to include JsonHelpers methods in Rspec tests 198 | config.include Request::JsonHelpers, :type => :controller 199 | # ... 200 | end 201 | ---- 202 | 203 | After that if we run our tests again, everything should be green again. So let's commit this before adding more code: 204 | 205 | [source,bash] 206 | ---- 207 | $ git add . 208 | $ git commit -m "Refactors the json parse method" 209 | ---- 210 | 211 | == Refactoring the format param 212 | 213 | We want to remove the `format` param sent on every request and instead of that let's handle the response we are expecting through headers. This is extremely easy just by adding one line to our `users_controller_spec.rb` file: 214 | 215 | [source,ruby] 216 | .spec/controllers/api/v1/users_controller_spec.rb 217 | ---- 218 | RSpec.describe Api::V1::UsersController, type: :controller do 219 | before(:each) { request.headers['Accept'] = "application/vnd.marketplace.v1, application/json" } 220 | ---- 221 | 222 | By adding this line, you can now remove all the `format` param we were sending on each request and forget about it for the whole application, as long as you include the `Accept` header with the JSON mime type. 223 | 224 | Wait we are not over yet! We can add another header to our request that will help us describe the data contained we are expecting from the server to deliver. We can achieve this fairly easy by adding one more line specifying the `Content-Type` header: 225 | 226 | [source,ruby] 227 | .spec/controllers/api/v1/users_controller_spec.rb 228 | ---- 229 | RSpec.describe Api::V1::UsersController, type: :controller do 230 | before(:each) { request.headers['Accept'] = "application/vnd.marketplace.v1, application/json" } 231 | before(:each) { request.headers['Content-Type'] = 'application/json' } 232 | ---- 233 | 234 | And again if we run our tests we can see they are all nice and green: 235 | 236 | [source,bash] 237 | ---- 238 | $ bundle exec rspec spec/controllers/api/v1/users_controller_spec.rb 239 | ............. 240 | 241 | Finished in 1.44 seconds (files took 0.4734 seconds to load) 242 | 13 examples, 0 failures 243 | ---- 244 | 245 | As always this is a good time to commit: 246 | 247 | [source,bash] 248 | ---- 249 | $ git commit -am "Factorize format for unit tests" 250 | ---- 251 | 252 | == Refactor before actions 253 | 254 | I'm very happy with the code we got so far but we can still improve it a little bit. The first thing that comes to my mind is to group the three custom headers being added before each request: 255 | 256 | [source,ruby] 257 | .spec/controllers/api/v1/users_controller_spec.rb 258 | ---- 259 | #... 260 | before(:each) { request.headers['Accept'] = "application/vnd.marketplace.v1, application/json" } 261 | before(:each) { request.headers['Content-Type'] = 'application/json' } 262 | ---- 263 | 264 | This is good but not good enough because we will have to add this five lines of code for each file. If for some reason we are changing this (let's say the response type to `xml`) well you do the math. But don't worry I provide you a solution which will solve all these problems. 265 | 266 | First of all we have to extend our `request_helpers.rb` file to include another module, which I named `HeadersHelpers` and which will have the necessary methods to handle these custom headers 267 | 268 | [source,ruby] 269 | .spec/support/request_helpers.rb 270 | ---- 271 | module Request 272 | # ... 273 | module HeadersHelpers 274 | def api_header(version = 1) 275 | request.headers['Accept'] = "application/vnd.marketplace.v#{version}" 276 | end 277 | 278 | def api_response_format(format ='application/json') 279 | request.headers['Accept'] = "#{request.headers['Accept']}, #{format}" 280 | request.headers['Content-Type'] = format 281 | end 282 | 283 | def include_default_accept_headers 284 | api_header 285 | api_response_format 286 | end 287 | end 288 | end 289 | ---- 290 | 291 | As you can see I broke the calls into two methods: one for setting the API header and the other one for setting the response format. Also and for convenience I wrote a method `include_default_accept_headers` for calling those two. 292 | 293 | And now to call this method before each of our test cases we can add the `before` hook footnote:[An hook allow you to run a specific method when a method is called] on the _Rspec.configure_ block at `spec_helper.rb` file, and make sure we specify the type to `:controller`, as we don't to run this on unit tests. 294 | 295 | [source,ruby] 296 | .spec/rails_helper.rb 297 | ---- 298 | # ... 299 | RSpec.configure do |config| 300 | # ... 301 | config.include Request::HeadersHelpers, :type => :controller 302 | config.before(:each, type: :controller) do 303 | include_default_accept_headers 304 | end 305 | # ... 306 | end 307 | ---- 308 | 309 | After adding this lines we can remove the before hooks on the `users_controller_spec.rb` file and check that our tests are still passing. You can review a full version of the `spec_helper.rb` file below: 310 | 311 | [source,ruby] 312 | .spec/rails_helper.rb 313 | ---- 314 | require 'spec_helper' 315 | ENV['RAILS_ENV'] ||= 'test' 316 | require File.expand_path('../../config/environment', __FILE__) 317 | # Prevent database truncation if the environment is production 318 | abort("The Rails environment is running in production mode!") if Rails.env.production? 319 | require 'rspec/rails' 320 | 321 | Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } 322 | 323 | begin 324 | ActiveRecord::Migration.maintain_test_schema! 325 | rescue ActiveRecord::PendingMigrationError => e 326 | puts e.to_s.strip 327 | exit 1 328 | end 329 | 330 | RSpec.configure do |config| 331 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 332 | config.use_transactional_fixtures = true 333 | 334 | config.include Devise::Test::ControllerHelpers, type: :controller 335 | config.include Request::JsonHelpers, :type => :controller 336 | config.include Request::HeadersHelpers, :type => :controller 337 | config.before(:each, type: :controller) do 338 | include_default_accept_headers 339 | end 340 | 341 | config.infer_spec_type_from_file_location! 342 | config.filter_rails_from_backtrace! 343 | end 344 | ---- 345 | 346 | Well now I do feel satisfied with the code, let's commit the changes: 347 | 348 | [source,bash] 349 | ---- 350 | $ git commit -am "Refactors test headers for each request" 351 | ---- 352 | 353 | Remember you can review the code up to this point at the https://github.com/madeindjs/api_on_rails[GitHub repository]. 354 | 355 | == Conclusion 356 | 357 | Nice job on finishing this chapter. Although it was a short one it was a crucial step as this will help us write better and faster tests. On next chapter we will add the authentication mechanism so we'll be using across the application as well as limiting the access for certain actions. 358 | -------------------------------------------------------------------------------- /rails6/en/chapter02-api.adoc: -------------------------------------------------------------------------------- 1 | [#chapter02-api] 2 | = The API 3 | 4 | In this section, I'll outline the application. By now, you should have read the previous chapter. If you did not read it, I recommend you to do it. 5 | 6 | You can clone the project until this point with: 7 | 8 | [source,bash] 9 | ---- 10 | $ git checkout tags/checkpoint_chapter02 11 | ---- 12 | 13 | To summarize, we simply generated our Rails application and made our first commit. 14 | 15 | 16 | == Planning the application 17 | 18 | Our application will be quite simple. It will consist of five models. Don't worry if you don't understand what's going on. We will review and develop each of these resources as we move forward with the tutorial. 19 | 20 | .Diagram of Market Place API models 21 | ---- 22 | +---------+ +---------+ 23 | | User +---->+Product | 24 | +---------+ +---------+ 25 | | | 26 | v v 27 | +---------+ +---------+ 28 | |Order +---->+Placement| 29 | +---------+ +---------+ 30 | ---- 31 | 32 | We will not build views for displaying or interacting with the API, so not to make this a huge tutorial, I'll let that to you. There are plenty of options out there like javascript frameworks (https://angularjs.org/[Angular], https://vuejs.org/[Vue.js], https://reactjs.org/[React.js]). 33 | 34 | By this point, you must be asking yourself: 35 | 36 | > all right, but I need to explore or visualize the API we will be building? 37 | 38 | That's fair. Probably if you google something related to API exploring, an application called https://www.getpostman.com/[Postman] will pop. It is great software, but we won't be using that anyway because we'll use *cURL*, allowing anybody to reproduce requests on any computer. 39 | 40 | == Setting the API 41 | 42 | An API is defined by http://en.wikipedia.org/wiki/Application_programming_interface[wikipedia] as _an application programming interface (API) specifies how some software components should interact with each other._ In other words, the way systems interact with each other through a common interface, in our case, a web service built with JSON. There are other kinds of communication protocols like SOAP, but we are not covering that here. 43 | 44 | As the Internet media type standard, JSON is widely accepted, readable, extensible, and easy to implement. Many of the current frameworks consume JSON APIs by default (https://angularjs.org/[Angular] or https://vuejs.org/[Vue.js], for example). There are also great libraries for Objective-C too like https://github.com/AFNetworking/AFNetworking[AFNetworking] or http://restkit.org/[RESTKit]. There are probably good solutions for Android, but I might not be the right person to recommend something because of my lack of experience in that development platform. 45 | 46 | All right. So we are building our API with JSON. There are many ways to achieve this. The first thing that comes to mind would be just to start adding routes defining the endpoints. This may be bad because they may not have a http://www.w3.org/2005/Incubator/wcl/matching.html[URI pattern] clear enough to know which resource is being exposed. The protocol or structure I'm talking about is http://en.wikipedia.org/wiki/Representational_state_transfer[REST] which stands for Representational State Transfer and by Wikipedia definition 47 | 48 | [source,soap] 49 | ---- 50 | aService.getUser("1") 51 | ---- 52 | 53 | And in REST you may call a URL with a specific HTTP request, in this case with a GET request: 54 | 55 | RESTful APIs must follow at least three simple guidelines: 56 | 57 | * A base http://en.wikipedia.org/wiki/Uniform_resource_identifier[URI], such as `http://example.com/resources/`. 58 | * An Internet media type to represent the data is commonly JSON and is commonly set through header exchange. 59 | * Follows the standard http://en.wikipedia.org/wiki/HTTP_method#Request_methods[HTTP Methods] such as GET, POST, PUT, DELETE. 60 | ** *GET*: Reads the resource or resources defined by the URI pattern 61 | ** *POST*: Creates a new entry into the resources collection 62 | ** *PUT*: Updates a collection or member of the resources 63 | ** *DELETE*: Destroys a collection or member of the resources 64 | 65 | This might not be clear enough or may look like a lot of information to digest, but hopefully, it'll get a lot easier to understand as we move on with the tutorial. 66 | 67 | === Routes, Constraints and Namespaces 68 | 69 | Before start typing any code, we prepare the code with git. We'll be using a branch per chapter, upload it to GitHub and then merge it on `master` branch. So let's get started. Open the terminal, `cd` to the `market_place_api` directory and type in the following: 70 | 71 | [source,bash] 72 | ---- 73 | $ git checkout -b chapter02 74 | Switched to a new branch 'chapter02' 75 | ---- 76 | 77 | We will only be working on the `config/routes.rb`, as we are just going to set the constraints and the default response `format` for each request. 78 | 79 | [source,ruby] 80 | .config/routes.rb 81 | ---- 82 | Rails.application.routes.draw do 83 | # ... 84 | end 85 | ---- 86 | 87 | First of all, erase all commented code that comes within the file. We are not gonna need it. Then commit it, just as a warm-up: 88 | 89 | [source,bash] 90 | ---- 91 | $ git add config/routes.rb 92 | $ git commit -m "Removes comments from the routes file" 93 | ---- 94 | 95 | We are going to isolate the API controllers under a namespace. With Rails, this is fairly simple: you just have to create a folder under the `app/controllers` named `API`. The name is important because that's the namespace we'll use for managing the controllers for the API endpoints. 96 | 97 | [source,bash] 98 | ---- 99 | $ mkdir app/controllers/api 100 | ---- 101 | 102 | Then we add that namespace into our `routes.rb` file: 103 | 104 | [source,ruby] 105 | .config/routes.rb 106 | ---- 107 | Rails.application.routes.draw do 108 | # API definition 109 | namespace :api do 110 | # We are going to list our resources here 111 | end 112 | end 113 | ---- 114 | 115 | By defining a namespace under the `routes.rb` file. Rails will automatically map that namespace to a directory matching the name under the _controllers_ folder, in our case the `api/`` directory. 116 | 117 | .Rails media types supported 118 | **** 119 | Rails can handle up to 35 different media types, you can list them by accessing the SET class under de Mime module: 120 | 121 | [source,bash] 122 | ---- 123 | $ rails c 124 | 2.6.3 :001 > Mime::SET.collect(&:to_s) 125 | => ["text/html", "text/plain", "text/javascript", "text/css", "text/calendar", "text/csv", "text/vcard", "text/vtt", "image/png", "image/jpeg", "image/gif", "image/bmp", "image/tiff", "image/svg+xml", "video/mpeg", "audio/mpeg", "audio/ogg", "audio/aac", "video/webm", "video/mp4", "font/otf", "font/ttf", "font/woff", "font/woff2", "application/xml", "application/rss+xml", "application/atom+xml", "application/x-yaml", "multipart/form-data", "application/x-www-form-urlencoded", "application/json", "application/pdf", "application/zip", "application/gzip"] 126 | ---- 127 | **** 128 | 129 | This is important because we are going to be working with JSON, one of the built-in http://en.wikipedia.org/wiki/Internet_media_type[MIME types] accepted by Rails, so we just need to specify this format as the default one: 130 | 131 | [source,ruby] 132 | .config/routes.rb 133 | ---- 134 | Rails.application.routes.draw do 135 | # API definition 136 | namespace :api, defaults: { format: :json } do 137 | # We are going to list our resources here 138 | end 139 | end 140 | ---- 141 | 142 | Up to this point, we have not made anything crazy. What we want to generate is a _base_uri_ which includes the API version. But let's commit changes before going to the next section: 143 | 144 | [source,bash] 145 | ---- 146 | $ git add config/routes.rb 147 | $ git commit -m "Set the routes constraints for the API" 148 | ---- 149 | 150 | == Api versioning 151 | 152 | At this point, we should have a nice route mapping using a namespace. Your `routes.rb` file should look like this: 153 | 154 | [source,ruby] 155 | .config/routes.rb 156 | ---- 157 | Rails.application.routes.draw do 158 | # API definition 159 | namespace :api, defaults: { format: :json } do 160 | # We are going to list our resources here 161 | end 162 | end 163 | ---- 164 | 165 | Now it is time to set up some other constraints for versioning purposes. You should care about versioning your application from the beginning since this will give a better structure to your API. When changes need to be made, you can give developers who are consuming your API the opportunity to adapt to the new features while the old ones are being deprecated. There is an excellent http://railscasts.com/episodes/350-rest-api-versioning[railscast] explaining this. 166 | 167 | To set the version for the API, we first need to add another directory under the `API` we created: 168 | 169 | [source,bash] 170 | ---- 171 | $ mkdir app/controllers/api/v1 172 | ---- 173 | 174 | This way we can namespace our api into different versions very easily, now we just need to add the necessary code to the `routes.rb` file: 175 | 176 | [source,ruby] 177 | .config/routes.rb 178 | ---- 179 | Rails.application.routes.draw do 180 | # Api definition 181 | namespace :api, defaults: { format: :json } do 182 | namespace :v1 do 183 | # We are going to list our resources here 184 | end 185 | end 186 | end 187 | ---- 188 | 189 | By this point, the API is now scoped via the URL. For example, with the current configuration, an endpoint for retrieving a product would be like . 190 | 191 | 192 | .Common API patterns 193 | **** 194 | You can find many approaches to set up the _base_uri_ when building an API following different patterns, assuming we are versioning our API: 195 | 196 | * `api.example.com/`: In my opinion, this is the way to go, gives you a better interface and isolation, and in the long term can help you to http://www.makeuseof.com/tag/optimize-your-dns-for-faster-internet/[quickly scalate] 197 | * `example.com/api/`: This pattern is very common, and it is actually a good way to go when you don't want to namespace your API under a subdomain 198 | * `example.com/api/v1`: it seems like a good idea by setting the version of the API through the URL seems like a more descriptive pattern, but this way you enforce the version to be included on URL on each request, so if you ever decide to change this pattern, this becomes a problem of maintenance in the long-term 199 | 200 | There are some practices in API building that recommend not to version the API via the URL. That's true. The developer should not be aware of the version he's using. For simplicity, I have chosen to set aside this convention, which we will be able to apply in a second phase. 201 | **** 202 | 203 | It is time to commit: 204 | 205 | [source,bash] 206 | ---- 207 | $ git commit -am "Set the versioning namespaces for API" 208 | ---- 209 | 210 | We are at the end of our chapter. Therefore, it is time to apply all our modifications to the master branch by making a _merge_. To do this, we place ourselves on the `master` branch and we _merge_ `chapter02`: 211 | 212 | [source,bash] 213 | ---- 214 | $ git checkout master 215 | $ git merge chapter02 216 | ---- 217 | 218 | == Conclusion 219 | 220 | I know it's been a long way, but you made it, don't give up this is just our small scaffolding for something big, so keep it up. In the meantime, and if you feel curious, some gems handle this kind of configuration: 221 | 222 | * https://github.com/Sutto/rocket_pants[RocketPants] 223 | * https://github.com/bploetz/versionist[Versionist] 224 | 225 | I'm not covering those in this book since we are trying to learn how to implement this kind of functionality, but it is good to know. By the way, the code up to this point is https://github.com/madeindjs/market_place_api_6/releases/tag/checkpoint_chapter03[here]. 226 | 227 | 228 | === Quiz 229 | 230 | To make sure that you understood this chapter, try to answer these questions: 231 | 232 | Which guideline do you must follow in a RESTfull API:: 233 | . Follows the standard HTTP Methods such as GET, POST, PUT, DELETE. 234 | . Buy a specific domain which is compliant with RESTFull API. 235 | . Use JSON format. 236 | 237 | Which file correspond to routes in a Rails application:: 238 | . `config/routes.rb` 239 | . `app/controller` 240 | . `config/application.rb` 241 | 242 | Which Rails feature we used to build our API versioning:: 243 | . A namespace like `namespace :v1`. 244 | . A new controller. 245 | 246 | Which HTTP method allow you to updates a collection or member of the resources:: 247 | . `POST` 248 | . `GET` 249 | . `PUT` 250 | 251 | How did you merge your branch at the end of this chapter:: 252 | . I `checkout` on `master` branch then I `merge` branch `chapter02`. 253 | . I `merge` branch `master` into `chapter02`. 254 | . `git config --global user.name "John Doe"` 255 | 256 | Take your time to answer. Once you resolved these questions, go to the next page to get responses. 257 | 258 | <<< 259 | 260 | ==== Answers 261 | 262 | Which guideline do you must follow in a RESTfull API:: Follows the standard HTTP methods such as GET, POST, PUT, DELETE. If you forgot what these methods mean, go 263 | 264 | Which file correspond to routes in a Rails application:: `config/routes.rb`. This file contains all application's route. 265 | 266 | Which Rails feature we used to build our API versioning:: a namespace like `namespace :v1`. Keep in mind that a namespace is a sort of route prefix which allows you to order some endpoint in the same "folder". 267 | 268 | Which HTTP method allows you to updates a collection or member of the resources:: `PUT`. `GET` allow you to access a resource and `POST` to create a new resource. 269 | 270 | How did you merge your branch at the end of this chapter:: I `checkout` on `master` branch then I `merge` branch `chapter02`. 271 | 272 | === Go further 273 | 274 | To go further, I recommend you to use Github or Gitlab to open a Pull Request with your `chapter02` branch. This will allow you to keep a clean history of what you did and modification. You can add a pretty description of why you did these modifications and how you organized your code. Once the pull request seems good, you can merge it. 275 | --------------------------------------------------------------------------------