From 7940083e59212bd8fc895a898e736b88e1727835 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 3 Jul 2024 16:44:50 +0530 Subject: [PATCH 1/5] CLI Basics: Remove echo mention since no prior references (#28334) --- foundations/installations/command_line_basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foundations/installations/command_line_basics.md b/foundations/installations/command_line_basics.md index a82642adb6b..6670b81c82d 100644 --- a/foundations/installations/command_line_basics.md +++ b/foundations/installations/command_line_basics.md @@ -108,7 +108,7 @@ Many of these resources assume you're using a Mac or Linux environment. If you d 1. Create a new directory in your home directory with the name `test`. 1. Navigate to the `test` directory. - 1. Create a new file called `test.txt`. *Hint: use the `touch` or `echo` command.* + 1. Create a new file called `test.txt`. *Hint: use the `touch` command.* 1. Open your newly created file in VSCode, make some changes, save the file, and close it. 1. Navigate back out of the `test` directory. 1. Delete the `test` directory. From 2bba6151cf851bfdd6b328a89c1a9e1de116d442 Mon Sep 17 00:00:00 2001 From: MaoShizhong <122839503+MaoShizhong@users.noreply.github.com> Date: Wed, 3 Jul 2024 13:53:09 +0100 Subject: [PATCH 2/5] CONTRIBUTING.md: Mention potential multiple passes of fix script (#28331) --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b662bf93126..717e06f30ee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,4 +31,6 @@ To help enforce the layout specified in our layout style guide, we use [markdown - Lint projects: `npm run lint:project -- "./path/to/project"` - Autofix projects: `npm run fix:project -- "./path/to/project"` +In some cases, you may need to run a fix script more than once to catch and fix all fixable errors. This typically occurs when a line has multiple errors affecting the same parts and fix actions collide, so Markdownlint only applies some of the fixes. + With either of these two methods, keep in mind that not all issues that get flagged will have an autofix available. Some rules require fixes that are more dependent on context and cannot - and should not - be automatically fixed, such as our custom rule `TOP001` for descriptive link text. From 88383698c32376d1564c9f37e062c131c5b86fb3 Mon Sep 17 00:00:00 2001 From: MaoShizhong <122839503+MaoShizhong@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:04:17 +0100 Subject: [PATCH 3/5] README.md Fix markdown style (#28332) --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9c61741316f..bb58f57138b 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,17 @@ Our community can be found on the [TOP Discord server](https://discord.gg/fbFCkY The Odin Project depends on open-source contributions to improve, grow, and thrive. We welcome contributors of all experience levels and backgrounds to help maintain this awesome curriculum and community. If you would like to contribute to our curriculum, be sure to thoroughly read our [contributing guide](https://github.com/TheOdinProject/.github/blob/main/CONTRIBUTING.md). Some of the things you can do to contribute to our curriculum include: -* Correct typos and other grammar errors. -* Rewrite parts of existing lessons to make them clearer and easier to understand. -* Fix broken links. -* Add new resource links you think would make a lesson better. -* Work on entirely new lessons after getting approval. + +- Correct typos and other grammar errors. +- Rewrite parts of existing lessons to make them clearer and easier to understand. +- Fix broken links. +- Add new resource links you think would make a lesson better. +- Work on entirely new lessons after getting approval. **Happy Coding!** -\* See [license.md](https://github.com/TheOdinProject/curriculum/blob/main/license.md) for usage details. +See [license.md](https://github.com/TheOdinProject/curriculum/blob/main/license.md) for usage details. ___ -Created by [Erik Trautman](http://www.github.com/eriktrautman) \ No newline at end of file + +Created by [Erik Trautman](http://www.github.com/eriktrautman). From 4b5bf575e487e63c383e2ae5c8c2206eecaed702 Mon Sep 17 00:00:00 2001 From: Juan Arismendi Diaz <141862378+McHeph@users.noreply.github.com> Date: Wed, 3 Jul 2024 19:12:57 -0300 Subject: [PATCH 4/5] Linting and RuboCop lesson: Fix weird phrasing (#28338) * Fix weird phrasing * Fix markdown changes introduced on previous commit --- ruby/object_oriented_programming_basics/linting_and_rubocop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/object_oriented_programming_basics/linting_and_rubocop.md b/ruby/object_oriented_programming_basics/linting_and_rubocop.md index 71a3e4af641..4207b091801 100644 --- a/ruby/object_oriented_programming_basics/linting_and_rubocop.md +++ b/ruby/object_oriented_programming_basics/linting_and_rubocop.md @@ -226,7 +226,7 @@ This will disable the `AbcSize` Cop from `Metrics` department between those comm Some rules are a lot more arbitrary - the Style department is going to be the prime ground for strong arguments about things that don't really matter - like double-quoting all strings vs making a distinction between plain strings and string interpolation. Perhaps you have strong feelings about quotes, so let's help you out by showing you how to show them to RuboCop. -Start by creating a `.rubocop.yml` file using the command touch or nano(nano will open the text editor right away). Don't forget the it must a dotfile, meaning it needs to have a dot before its name. Now, you need to find out what rule you want to change or disable. For the possible options always consult the documentation - not every Cop is just a simple on/off, there might be more options. As an example, we'll be changing the rules regarding strings, frozen string literals and we'll enable NewCops. +Start by creating a `.rubocop.yml` file using the command touch or nano(nano will open the text editor right away). Don't forget that it must be a dotfile, meaning it needs to have a dot before its name. Now, you need to find out what rule you want to change or disable. For the possible options always consult the documentation - not every Cop is just a simple on/off, there might be more options. As an example, we'll be changing the rules regarding strings, frozen string literals and we'll enable NewCops. ```yaml # This is .rubocop.yml in ~/ From f7f42c0f47b0773aa87a1aa91d8d0d479baad820 Mon Sep 17 00:00:00 2001 From: SeanAverS Date: Wed, 3 Jul 2024 15:26:33 -0700 Subject: [PATCH 5/5] Rails External APIs: Improve accessibility of link text (#28312) * update link text to improve accessibility * fix linting errors and change 2 typos * Fix markdown linting errors * Fix markdown linting errors * Remove duplicate lines Co-authored-by: MaoShizhong <122839503+MaoShizhong@users.noreply.github.com> --------- Co-authored-by: MaoShizhong <122839503+MaoShizhong@users.noreply.github.com> --- .../apis/working_with_external_apis.md | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/ruby_on_rails/apis/working_with_external_apis.md b/ruby_on_rails/apis/working_with_external_apis.md index 809540154cf..8e8b1c3e7d0 100644 --- a/ruby_on_rails/apis/working_with_external_apis.md +++ b/ruby_on_rails/apis/working_with_external_apis.md @@ -6,7 +6,7 @@ Most popular services offer APIs so developers can interface with them (they lov If you go to the documentation for an API, it can sometimes be a bit overwhelming because much of the material sort of assumes that you know what you're doing, but some are definitely better than others. There are also elements that are common across almost all of them. The more you work with APIs (and get the hang of the authentication flow), the easier they get. You'll be making mashups in no time. -This lesson will cover some general steps that are common across APIs and will do high level overviews of some of the methods for authenticating with APIs like Omniauth. Try to gain as much conceptual understanding as you can here and use the documentation each gem or API provides to help with the implementation. If you find great free learning resources that explain APIs, please let us know [(make a pull request and add an additional resource at the bottom of this page)](https://github.com/TheOdinProject/curriculum)! +This lesson will cover some general steps that are common across APIs and will do high level overviews of some of the methods for authenticating with APIs like Omniauth. Try to gain as much conceptual understanding as you can here and use the documentation each gem or API provides to help with the implementation. If you find great free learning resources that explain APIs, you can [suggest resources via a GitHub issue in our curriculum repo](https://github.com/TheOdinProject/curriculum/issues/new/choose)! ### Lesson overview @@ -32,9 +32,9 @@ You'll typically also get a "secret key" or similarly named code. Whereas the A Most APIs require a different type of "security clearance" for different requests: 1. You can usually make innocuous requests like asking for posts from X's (formerly known as Twitter) API with straightforward and unauthenticated GET requests. You can make these from any command line or an application like [Postman](http://getpostman.com). These types of API requests are usually severely rate limited to incentivize you to sign up. -2. The next layer is making requests that include your API key. These are still usually fairly innocuous things (like getting public data) and limited by the API's pricing tiers. -3. More sensitive requests like asking for specific user data or submitting/modifying/deleting data will likely require you to use an authentication process involving your secret token. We'll cover the basics of this in the project. Rates for these requests are subject to the API pricing tiers. -4. Oftentimes, you actually want to make requests on behalf of a user. For instance, showing a user a dashboard of all their posts and Facebook posts together would require asking X for that user's posts and Facebook for that user's posts. This can involve a LOT of requests over a large user base, but luckily you're actually able to make them on the user's behalf by asking for the user's permission. We'll cover this as well later, but basically you send the user to the API provider's site to sign in, then the API provider will give you a user-specific token to use when making requests on their behalf in the future. Rates for this are usually more advantageous because they are covered in a per-user bucket. We typically use the OAuth protocol for this, as described below. +1. The next layer is making requests that include your API key. These are still usually fairly innocuous things (like getting public data) and limited by the API's pricing tiers. +1. More sensitive requests like asking for specific user data or submitting/modifying/deleting data will likely require you to use an authentication process involving your secret token. We'll cover the basics of this in the project. Rates for these requests are subject to the API pricing tiers. +1. Oftentimes, you actually want to make requests on behalf of a user. For instance, showing a user a dashboard of all their posts and Facebook posts together would require asking X for that user's posts and Facebook for that user's posts. This can involve a LOT of requests over a large user base, but luckily you're actually able to make them on the user's behalf by asking for the user's permission. We'll cover this as well later, but basically you send the user to the API provider's site to sign in, then the API provider will give you a user-specific token to use when making requests on their behalf in the future. Rates for this are usually more advantageous because they are covered in a per-user bucket. We typically use the OAuth protocol for this, as described below. ### Versions @@ -77,57 +77,60 @@ OAuth 2.0 is actually pretty complicated, so we'll just cover the basic process. Basically (still using Facebook as an example): 1. User tries to access a page on your app and you ask the user to login -2. User chooses the "Login With Facebook" option -3. User is redirected to a Facebook page asking them to review the permissions you are asking for and telling them to sign in. The URI will contain parameters that tell Facebook who your application is and possibly which URI they should submit their response to (or maybe you specified this as a part of your API registration process with them). -4. User decides you seem like a fun application so they'll allow you to see their email address and post to their timeline. User signs in to their Facebook account. Facebook creates an authorization code and sends it back to your application's callback URI. -5. The user waits while your application takes that authorization code and uses it to ask Facebook for the real good stuff. Facebook makes sure your application is the same one the user authorized, then POSTs back to you a unique authentication token for the user (which likely expires in 90 days) and any data you asked for up front (like email address). -5. You store the user's unique token in your database and use it, along with your application key(s), to make any subsequent requests on the user's behalf. +1. User chooses the "Login With Facebook" option +1. User is redirected to a Facebook page asking them to review the permissions you are asking for and telling them to sign in. The URI will contain parameters that tell Facebook who your application is and possibly which URI they should submit their response to (or maybe you specified this as a part of your API registration process with them). +1. User decides you seem like a fun application so they'll allow you to see their email address and post to their timeline. User signs in to their Facebook account. Facebook creates an authorization code and sends it back to your application's callback URI. +1. The user waits while your application takes that authorization code and uses it to ask Facebook for the real good stuff. Facebook makes sure your application is the same one the user authorized, then POSTs back to you a unique authentication token for the user (which likely expires in 90 days) and any data you asked for up front (like email address). +1. You store the user's unique token in your database and use it, along with your application key(s), to make any subsequent requests on the user's behalf. -See [this brief overview of OAuth 2.0](http://tutorials.jenkov.com/oauth2/overview.html) for an overview. Then check out [this more substantive explanation from tutsplus.com](https://code.tutsplus.com/articles/oauth-20-the-good-the-bad-the-ugly--net-33216). +See this brief [overview of OAuth 2.0](http://tutorials.jenkov.com/oauth2/overview.html). Then check out this [more substantive explanation of OAuth 2.0 from tutsplus.com](https://code.tutsplus.com/articles/oauth-20-the-good-the-bad-the-ugly--net-33216). #### Implementing OAuth 2.0 in Rails -- Use OmniAuth! This sounds horribly complicated! Someone must have made a gem for it... -Luckily someone has. Many someones, actually. There is a generic OAuth gem called `omniauth` (docs available [on GitHub](https://github.com/intridea/omniauth)) and then a separate gem which provides a specific authentication strategy for every major API (see the list [HERE](https://github.com/intridea/omniauth/wiki/List-of-Strategies)). Once you've gone through things with one of them, you'll become comfortable with all of them. It's also worth noting that if you install and use [Devise](https://github.com/heartcombo/devise) (to handle your user model, for example), it comes with support for Omniauth built in! Refer to the [documentation](https://github.com/heartcombo/devise/wiki/OmniAuth%3A-Overview) for details. +Luckily someone has. Many someones, actually. There is a generic OAuth gem called `omniauth` ([Omniauth documentation](https://github.com/intridea/omniauth)) and then a separate gem which provides a specific authentication strategy for every major API ([list of Omniauth strategies](https://github.com/intridea/omniauth/wiki/List-of-Strategies)). Once you've gone through things with one of them, you'll become comfortable with all of them. It's also worth noting that if you install and use [Devise](https://github.com/heartcombo/devise) (to handle your user model, for example), it comes with support for Omniauth built in! They have documentation on [how to integrate Devise with Omniauth](https://github.com/heartcombo/devise/wiki/OmniAuth%3A-Overview). Using Omniauth is much easier to learn by doing than reading a bunch of bullet points. You'll have the opportunity to implement it in your final project where you can ask questions if needed. ### SDKs -In addition to or instead of API access, many companies provide SDKs (software development kits). Usually these are Javascript libraries that contain all the code necessary to access their API. This can be useful because you're then able to access the API with Javascript methods instead of doing backflips on your own backend. It comes with the downside, however, of expanding your code base and forcing you to use their conventions for everything. +In addition to or instead of API access, many companies provide SDKs (software development kits). Usually these are JavaScript libraries that contain all the code necessary to access their API. This can be useful because you're then able to access the API with JavaScript methods instead of doing backflips on your own backend. It comes with the downside, however, of expanding your code base and forcing you to use their conventions for everything. We won't cover SDKs explicitly in this course but they should be well within reach to pick up by reading the documentation. ### Assignment
- 1. Watch [this Railscast on using Omniauth to allow X (formerly known as Twitter) Signin](http://railscasts.com/episodes/241-simple-omniauth-revised). - 2. Read through the [Omniauth documentation](https://github.com/intridea/omniauth) - 3. Pick an API that you really might like to interface with or a web product you use almost every day (e.g. Google, Facebook, Instagram...). Google for its docs, e.g. with "instagram api documentation", and have a look at them. Some docs are better than others, but they will be your source for understanding which methods you can call, what they will return, how to register your application to get an API key, and more useful tidbits. + + 1. Watch this Railscast on [using Omniauth to allow X (formerly known as Twitter) Signin](http://railscasts.com/episodes/241-simple-omniauth-revised). + 1. Read through the [Omniauth documentation](https://github.com/intridea/omniauth) + 1. Pick an API that you really might like to interface with or a web product you use almost every day (e.g. Google, Facebook, Instagram...). Google for its docs, e.g. with "instagram api documentation", and have a look at them. Some docs are better than others, but they will be your source for understanding which methods you can call, what they will return, how to register your application to get an API key, and more useful tidbits. +
-### Conclusion +#### Conclusion -APIs are fundamental to making rich web applications and they're also a lot of fun -- it makes your app feel a lot more "real" when you're able to let your users log in using Facebook or if you can display information from different sources across the web. If you're building a startup, it improves the user experience enough that you'll likely see an uptick in conversion rates. +APIs are fundamental to making rich web applications and they're also a lot of fun -- it makes your app feel a lot more "real" when you're able to let your users log in using Facebook or if you can display information from different sources across the web. If you're building a startup, it improves the user experience enough that you'll likely see an uptick in conversion rates. Working with external APIs can be incredibly rewarding because you're able to leverage functionality that others have spent a lot of time perfecting but also incredibly frustrating because they're all different and you have to rely on gems which are doing things behind the scenes that you're not entirely sure of. Over time, you'll start to see a lot of similarities between APIs and the procedure for working with them will feel more and more comfortable. To help get you there, the next project will have you working with an API and your final project will have you implementing signin via API as well. ### Knowledge check -This section contains questions for you to check your understanding of this lesson. If you’re having trouble answering the questions below on your own, review the material above to find the answer. -* What's the best way to locate an API's docs? -* What is an API key? -* How do you avoid including an API's secret token in your GitHub repo (e.g. hard coding it)? -* Why is it important to know which API version you're using? -* Why would a user prefer to sign into your site using Facebook instead of giving you a new password? -* What are the different types of "security clearance" for the different types of API requests you can make? +The following questions are an opportunity to reflect on key topics in this lesson. If you can't answer a question, click on it to review the material, but keep in mind you are not expected to memorize or master this knowledge. + +- [What's the best way to locate an API's docs?](#introduction) +- [What is an API key?](#first-steps) +- [How do you avoid including an API's secret token in your GitHub repo (e.g. hard coding it)?](#first-steps) +- [Why is it important to know which API version you're using?](#versions) +- [Why would a user prefer to sign into your site using Facebook instead of giving you a new password?](#oauth-and-login-via-api) +- [What are the different types of "security clearance" for the different types of API requests you can make?](#api-rates-and-security-tokens) ### Additional resources This section contains helpful links to related content. It isn't required, so consider it supplemental. -- See [This SO Post on interfacing with third-party APIs](http://stackoverflow.com/questions/6228870/interfacing-with-a-third-party-api-in-rails-opeing-urls-and-parsing-xml-json) for tips. +- See this Stack Overflow post on [interfacing with third-party APIs](http://stackoverflow.com/questions/6228870/interfacing-with-a-third-party-api-in-rails-opeing-urls-and-parsing-xml-json) for tips. - [RailsConf 2016 - From Zero to API Hero: Consuming APIs like a Pro by Cecy Correa](https://www.youtube.com/watch?v=Af5HDgvGuXk) -- Take a look at [this Medium article](https://revs.runtime-revolution.com/integrating-a-third-party-api-with-rails-5-134f960ddbba) over integrating a third party API with Rails 5. -- See this other [Medium Article](https://medium.com/food4fluctuations/using-an-api-in-rails-for-noobs-5e02edb0e56b) on creating a basic rails app using the OMDB API, an open source movie database. +- Take a look at this Medium article over [integrating a third party API with Rails 5](https://revs.runtime-revolution.com/integrating-a-third-party-api-with-rails-5-134f960ddbba). +- See this other Medium Article on [creating a basic Rails app using the OMDB API](https://medium.com/food4fluctuations/using-an-api-in-rails-for-noobs-5e02edb0e56b), an open source movie database.