{"id":18653500,"url":"https://github.com/fullstackacademy/api-example","last_synced_at":"2025-04-11T16:32:30.741Z","repository":{"id":76925967,"uuid":"56854482","full_name":"FullstackAcademy/api-example","owner":"FullstackAcademy","description":null,"archived":false,"fork":false,"pushed_at":"2016-08-09T23:18:36.000Z","size":13,"stargazers_count":4,"open_issues_count":0,"forks_count":7,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-25T16:16:04.414Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FullstackAcademy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-22T12:40:37.000Z","updated_at":"2019-12-24T04:09:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"f32ebc0c-7e36-4ebd-8b05-7230a959e9e6","html_url":"https://github.com/FullstackAcademy/api-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FullstackAcademy%2Fapi-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FullstackAcademy%2Fapi-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FullstackAcademy%2Fapi-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FullstackAcademy%2Fapi-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FullstackAcademy","download_url":"https://codeload.github.com/FullstackAcademy/api-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248441302,"owners_count":21103961,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T07:12:05.692Z","updated_at":"2025-04-11T16:32:30.731Z","avatar_url":"https://github.com/FullstackAcademy.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [Signup Link!](https://learn.fullstackacademy.com/signup?cohort=571a663dd5e33e030020cade)\n# Web APIs\n\n1. [Detailed Background](#detailed-background)\n  - [HTTP](#http)\n  - [Anatomy of a request](#anatomy-of-a-request)\n  - [Anatomy of a response](#anatomy-of-a-response)\n  - [The cycle](#the-cycle)\n  - [REST](#rest)\n2. [Our first API Client](#our-first-api-client)\n  - [Installing Node.js](#installing-node-js)\n  - [Setting up the Project](#setting-up-the-project)\n  - [The request](#the-request)\n3. [Our project](#our-project)\n  - [Structure](#structure)\n  - [Setting Up Your Own Web Server](#setting-up-your-own-web-server)\n  - [With Twilio](#with-twilio)\n  - [Challenge](#challenge)\n\n## Detailed Background\n\nNote: This might be more information than you need. I want you to have a complete picture.\n\n### HTTP\nThe internet as we know it (and nearly every web API) is built on top of the HTTP protocol. HTTP is a set of conventions that allow programs running on computers to send each other information. These programs have distinct roles. The _client_ initiates the communication by creating a _request_. The _server_ sends a _response_ the the request. Servers send one response per request.\n\n    ┌──────────┐                   ┌──────────┐\n    │          │◀───1. Request──── │          │\n    │   HTTP   │                   │   HTTP   │\n    │  Server  │                   │  Client  │\n    │          │────2. Response──▶ │          │\n    └──────────┘                   └──────────┘\n    \nSometimes when people talk about clients and servers they're talking about hardware. Other times they're talking about software. Today, we're talking about software. A server is a software program that responds to a client's request. A client is a program that sends requests to servers.\n\nYou know many HTTP clients already. Some live in your browser, others are on phones. Still more are in cars, thermostats, security systems and baby cameras.\n\n### Anatomy of a request\n\nRequests have several components:\n\n- Location - where the request is going\n  - Server - internet address of a computer running a server program\n  - Path - everything after the `.com`\n- Method - a somewhat arbitrary categorization tool. We'll get to this more when we talk about REST. Common methods include GET, POST, PUT, and DELETE\n- Headers - key, value pairs for sending more information\n- Body - binary data that is sometimes sent with the request\n\n### Anatomy of a response\n\nResponses have the following components:\n\n- Status code - a convention for describing disposition of the request. You probably already know one, 404 (not found). Status code 200 means \"OK.\"\n- Headers - key, value pairs describing metadata about the response\n- body - binary data\n\n### The cycle\n\n    ┌──────────────────────────────────────────────────────────────┐\n    │                            Client                            │\n    └┬─────────────────────────────────────────────────────────────┘\n     │GET /docs/index.html HTTP/1.1   ▲                             \n     │Host: www.test101.com           │HTTP/1.1 200 OK              \n     │Accept: image/gif, image/jpeg   │Date: Sun, 18 Oct 2009...    \n     │Accept-Language: en-us          │Server: Apache/2.2.14 (Win32)\n     │Accept-Encoding: gzip, deflate  │Last-Modified: Sat, 20 Nov...\n     │Content-Length: 25kb            │ETag: \"10000000565a5-2c-...\" \n     │User-Agent: Mozilla/4.0...      │Accept-Ranges: bytes         \n     │(blank line)                    │Content-Length: 44           \n     │                                │Connection: close            \n     │                                │Content-Type: text/html      \n     │                                │X-Pad: avoid browser bug     \n     │                                │                             \n     │                                │\u003chtml\u003e\u003cbody\u003e\u003ch1\u003eIt           \n     ▼                                │works!\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e    \n    ┌─────────────────────────────────┴────────────────────────────┐\n    │                            Server                            │\n    └──────────────────────────────────────────────────────────────┘\n\n### REST\n\nREST stands for [REpresentational State Transfer](https://en.wikipedia.org/wiki/Representational_state_transfer). It's a little complicated, but the gist is that it's convention on top of HTTP that standardizes the format of requests and responses for common tasks in web software.\n\nMost tasks on web applications can be categorized into the following 4 groups\n\n- Create\n- Read\n- Update\n- Delete\n\nYou can tweet, look at a tweet, edit a tweet (maybe? ¯\\_(ツ)_/¯), delete a tweet.\n\nYou can \"friend\" someone on facebook, see other people's friends, update a friend (relationship status? ¯\\_(ツ)_/¯), and unfriend someone.\n\nYou get the idea.\n\nREST is basically a mapping of HTTP request verbs and paths to these 4 common actions. \n\nHere's the mapping:\n\n| Purpose | Method | Path         |\n|---------|--------|--------------|\n| Create  | POST   | /            |\n| Read    | GET    | / or /someId |\n| Update  | PUT    | /someId      |\n| Delete  | DELETE | /someId      |\n\nThis might not make sense, so here's an example.\n\nIn Twitter's API, you might create a tweet like this:\n\n```\nPOST /api/tweets HTTP/1.1\nHost: www.twitterdotcom.com\nAccept: application/json\nAccept-Language: en-us\nAccept-Encoding: gzip, deflate\nContent-Length: 1kb\nAuthorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\n{\n  \"tweet\":\"omg lolz #yolo\"\n}\n```\n\nTwitter might respond like this:\n\n```\nHTTP/1.1 201 Created\nDate: Sun, 18 Oct 2018 08:56:53 GMT\nETag: \"10000000565a5-2c-3e94b66c2e680\"\nContent-Length: 44\nConnection: close\nContent-Type: application/json\n  \n{\n  \"id\": 1232244242422,\n  \"tweet\": \"omg lolz #yolo\",\n  tags: [\"yolo\"],\n  user: 2342342423423\n}\n```\n\nYou might update a tweet like this\n\n```\nPUT /api/tweets/1232244242422 HTTP/1.1\nHost: www.twitterdotcom.com\nAccept: application/json\nAccept-Language: en-us\nAccept-Encoding: gzip, deflate\nContent-Length: 1kb\nAuthorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\n{\n  \"tweet\":\"omg lolz #yolo #fun!\"\n}\n```\n\netc.\n\n## Our first API Client\n\n### Installing Node.js\n\n#### Linux\n\nOk so you guys might be somewhat on your own. You probably _don't_ want to just use your built in package manager because it will be hopelessly out of date. [Here](https://nodejs.org/en/download/package-manager/) are some great instructions for making the package managers work\n\n#### Mac \u0026 Windows\n\nHead to [node.js](https://nodejs.org/en/)s' website and download the installer from there. You can also use a package manager if you have one and know what you're doing.\n\nOnce Node is installed, fire up a shell (windows users, I really hope you have [Cygwin](https://www.cygwin.com/) if not, you might be looking on with a friend...) and run:\n\n```bash\n$ node --version\n```\n\nYou should get some version number. If you don't, flag me down and I'll help you.\n\n### Setting up the Project\n\nI've set up a starting point for you on in this repo. To download it, you can click on the download link on github, or use `git clone`. Once you have the project on your hard drive, direct your shell to the project. Here's how I would do it:\n\n```bash\n$ git clone ...\n$ cd ./api-example\n```\n\nThen run `$ npm install`. NPM (Node Package Manager) will read the `package.json` file in the directory and install needed dependencies.\n\n### The Request\n\nUse your favorite text editor to explore the directory. You should see something like\n\n```\n.\n├── example.js\n├── index.js\n├── package.json\n└── node_modules\n```\n\nOpen up `example.js`. See if you can predict what it will do. Once you've looked it up and down, run it!\n\n```bash\n$ node ./example.js\n```\n\nWhat you're getting back is the JSON representation of my github repositories.\n\n## Our Project\n\n### Structure\n\nWe're building a cool little system. When a user texts a phone number, the raspberry pi takes a photo and texts it back. To make this work we're going to use a service called Twilio. Twilio is an API that let's us easily write software with telephony features. We can send and receive texts, calls, and photos.\n\nOur program that is _both_ an HTTP client and an HTTP server. This may seem odd, but its actually quite common. Here's how our program fits into the ecosystem.\n\n    ┌──────────────────────────────────────────────────┐                                        \n    │              Verison, AT\u0026T, etc...               │                                        \n    └┬─────────────────────────────────────────────────┘    1. An incoming SMS triggers a cell  \n     │ ▲                                              ▲     provider to send a request to Twilio\n     │ │                                              │     2. Twilio Responds, indicating that \n     ▼ │                                              │     they received the message.          \n    ┌──┴──────────────────────────────────────────────┴┐                                        \n    │                      Twilio                      │                                        \n    └┬─────────────────────────────────────────────────┘    3. Twilio sends your server a       \n     │                                                ▲     request... waiting...               \n     │                                                │                                         \n     ▼                                                │                                         \n    ┌─────────────────────────────────────────────────┴┐                                        \n    │                   Your server                    │░                                       \n    └──────────────────────────────────────────────────┘░   4. Your server receives twilio's    \n     │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▲░░   request                             \n     │                                                │     5. Your server makes a request to   \n     │                                                │     the Raspberry Pi                    \n    ┌▼────────────────────────────────────────────────┴┐    6. The raspberry pi takes a photo   \n    │                     The RPI                      │    7. The raspberry pi responds to the \n    └──────────────────────────────────────────────────┘    request with the photo              \n                                                            8. Your server responds to twilio's \n                                                            request                             \n                                                            9 Twilio makes a new request to     \n                                                            Version, AT\u0026T, etc                  \n                                                                                                \n\n\n### Setting Up Your Own Web Server\n\nNode.js comes built with an `http` package which makes it simple to create basic servers. Open up `index.js` and start editing.\n\nFirst, require the `http` package.\n\n```js\nconst http = require('http');\n```\n\nThere's a method exposed on the `http` object called `createServer`. We're going to call that method.\n\n```js\nhttp.createServer()\n```\n\n`createServer` returns an HTTP Server object. This object has a `listen` method. We can call the listen method to tell the server to start listening on a port. We haven't talked about ports yet. For now, just think of them as radio frequencies. Our line should now look like:\n\n```js\nhttp.createServer().listen(1337);\n```\n\nSo great. Now we have an HTTP server, but it isn't doing anything for us! How do we specify the functionality of the server? Well the `createServer` method actually takes an argument. Its a function!\n\n```js\nhttp.createServer(function() {}).listen(1337);\n```\n\nThis is a pretty common pattern in javascript and many other languages. By passing a function into create server, we're telling how we want the server to behave. `http` will call our function whenever a request comes into the server. It will pass in two arguments to our function: an object representing the request, and another the response.\n\n```js\nhttp.createServer(function(request, response) {\n  \n}).listen(1337);\n```\n\nNow let's get the server saying something.\n\n```js\nhttp.createServer(function(request, response) {\n  response.writeHead(200);\n  response.end('Hi guys!');\n}).listen(1337);\n```\n\nFire up your server to test it\n\n```bash\n$ node index.js\n```\n\nNow direct your browser to http://localhost:1337\n\nNotice that your computer is running both a client program and a server program.\n\n### With Twilio\n\nGo to twilio.com and set up an account. You should be able to get a test number for free. But if not, numbers only cost $1/month. You can cancel them after today. Every text sent or received costs 1 cent.\n\nWhen you're setting up your phone number, Twilio will ask you what server they should send requests to. Your computer isn't running on the public internet! How will twilio get messages to you? You can use a service called ngrok to give your laptop a temporary domain name.\n\nYou can install it like this:\n\n```bash\n$ npm install -g ngrok\n```\n\nSome of you may need to `sudo` that command or find me for help correcting your permissions.\n\nOnce you have `ngrok` installed, you can set up a domain for your laptop like this\n\n```bash\n$ ngrok http 1337\n```\n\nIt will show you output like this\n\n```\nngrok by @inconshreveable                                                                                                                                                                 (Ctrl+C to quit)\n\nTunnel Status                 online\nUpdate                        update available (version 2.0.24, Ctrl-U to update)\nVersion                       2.0.19/2.0.25\nWeb Interface                 http://127.0.0.1:4040\nForwarding                    http://5a18a004.ngrok.io -\u003e localhost:1337\nForwarding                    https://5a18a004.ngrok.io -\u003e localhost:1337\n\nConnections                   ttl     opn     rt1     rt5     p50     p90\n                              0       0       0.00    0.00    0.00    0.00\n\n```\n\nYou can copy this part `http://5a18a004.ngrok.io` and give that to twilio.\n\nNow, you need to modify your web server to give the type of responses twilio is looking for.\n\nTry making your server look like this\n\n```js\nconst http = require('http');\n\nhttp.createServer(function (req, res) {\n    res.writeHead(200, {'Content-Type': 'text/xml'});\n    res.end(`\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n              \u003cResponse\u003e\n                  \u003cMessage\u003e\n                    \u003cBody\u003eWelcome to Twilio!\u003c/Body\u003e\n                    \u003cMedia\u003ehttp://i.imgur.com/Act0Q.gif\u003c/Media\u003e\n                  \u003c/Message\u003e\n              \u003c/Response\u003e`);\n\n}).listen(1337);\n```\n\nMake sure your server is restarted and your ngrok tunnel is open. Try sending a text to your number on twilio. You should get a funny response!\n\n### Challenge\n\nYour challenge is to modify the server to make requests to the raspberry pi server we wrote together.  When the twilio request comes to you, send me a request. I'll send you back a URL to a photo that I took because of the request. Then you forward that on to twilio.\n\nThe first one to finish gets my Raspberry\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffullstackacademy%2Fapi-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffullstackacademy%2Fapi-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffullstackacademy%2Fapi-example/lists"}