├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .prettierrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── development.md └── v1 │ ├── README.md │ ├── info.md │ ├── launches.md │ ├── payloads.md │ └── rockets.md ├── now.json ├── package.json ├── src ├── app.js ├── controllers │ └── v1 │ │ ├── info.js │ │ ├── launches.js │ │ ├── payloads.js │ │ └── rockets.js └── routes │ └── v1.js ├── test └── routes │ └── v1.test.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.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: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with a single custom sponsorship URL 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # General 61 | *.DS_Store 62 | .AppleDouble 63 | .LSOverride 64 | 65 | # Icon must end with two \r 66 | Icon 67 | 68 | 69 | # Thumbnails 70 | ._* 71 | 72 | # Files that might appear in the root of a volume 73 | .DocumentRevisions-V100 74 | .fseventsd 75 | .Spotlight-V100 76 | .TemporaryItems 77 | .Trashes 78 | .VolumeIcon.icns 79 | .com.apple.timemachine.donotpresent 80 | 81 | # Directories potentially created on remote AFP share 82 | .AppleDB 83 | .AppleDesktop 84 | Network Trash Folder 85 | Temporary Items 86 | .apdisk 87 | 88 | # MongoDB local files 89 | .schema.json -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "singleQuote": true 4 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Pull Request Steps 2 | 3 | **NOTE**: Make sure every change is covered by a unit test. If the change isn't 4 | covered, make sure to add a test for it. 5 | 6 | Fork the repo, make changes, add tests, commit, and submit a Pull Request 7 | 8 | ## Trello Board 9 | Take a look on our Trello board [here](https://trello.com/b/6zQjMaff) to see what's going on. 10 | 11 | ## Database additions / changes / updates 12 | 13 | 1. Open an issue with your correction, addition, or new data ideas 14 | 15 | 2. If approved, new data will be added to the database, and tests will be written to cover the new data 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Filipe Barros. 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

3 |

Image from It's Business Time Rocket Lab Mission

4 | 5 |

6 | 7 |

Rocket Lab REST API

8 | 9 |

10 | 11 |

12 | 13 |

An Open Source REST API for rocket and launch data

14 | 15 | ## Usage 16 | 17 | **Example Response** 18 | 19 | ```bash 20 | curl -s https://rocketlab-api.now.sh/v1/launches/latest | jq 21 | ``` 22 | 23 | ```json 24 | { 25 | "flight_number": 4, 26 | "mission_name": "ELaNa 19", 27 | "upcoming": false, 28 | "launch_year": "2018", 29 | "launch_date_unix": 1544941980, 30 | "launch_date_utc": "2018-12-16T06:33:00.000Z", 31 | "launch_date_local": "2018-12-16T18:33:00.000Z", 32 | "rocket": { 33 | "name": "Electron", 34 | "first_stage": { "engines": 9, "type": "Rutherford" }, 35 | "second_stage": { "engines": 1, "type": "Rutherford" }, 36 | "kick_stage": { "engines": 1, "type": "Curie" }, 37 | "payloads": [ 38 | { 39 | "norad_id": null, 40 | "name": "ALBUS", 41 | "nationality": "United States", 42 | "configuration": "CubeSat", 43 | "type": ["Technology"], 44 | "customer_name": "NASA", 45 | "manufacturer": "NASA Glenn Research Center", 46 | "mass_kg": 5, 47 | "orbit": "LEO" 48 | }, 49 | { 50 | "norad_id": null, 51 | "name": "CeREs", 52 | "nationality": "United States", 53 | "configuration": "CubeSat", 54 | "type": ["Magnetospheric Research"], 55 | "customer_name": "NASA", 56 | "manufacturer": "NASA Goddard Space Flight Center", 57 | "mass_kg": 4, 58 | "orbit": "LEO" 59 | }, 60 | { 61 | "norad_id": 43855, 62 | "name": "CHOMPTT", 63 | "nationality": "United States", 64 | "configuration": "CubeSat", 65 | "type": ["Technology"], 66 | "customer_name": "NASA", 67 | "manufacturer": "University of Florida", 68 | "mass_kg": 1, 69 | "orbit": "LEO" 70 | }, 71 | { 72 | "norad_id": null, 73 | "name": "CubeSail", 74 | "nationality": "United States", 75 | "configuration": "CubeSat", 76 | "type": ["Technology"], 77 | "customer_name": "NASA", 78 | "manufacturer": "University of Illinois at Urbana-Champaign", 79 | "mass_kg": null, 80 | "orbit": "LEO" 81 | }, 82 | { 83 | "norad_id": 43857, 84 | "name": "DaVinci", 85 | "nationality": "United States", 86 | "configuration": "CubeSat", 87 | "type": ["Technology", "Educational"], 88 | "customer_name": "NASA", 89 | "manufacturer": "North Idaho STEM Charter Academy", 90 | "mass_kg": 4, 91 | "orbit": "LEO" 92 | }, 93 | { 94 | "norad_id": null, 95 | "name": "ISX", 96 | "nationality": "United States", 97 | "configuration": "CubeSat", 98 | "type": ["Techology"], 99 | "customer_name": "NASA", 100 | "manufacturer": "SRI International/ California Polytechnic University", 101 | "mass_kg": 4, 102 | "orbit": "LEO" 103 | }, 104 | { 105 | "norad_id": null, 106 | "name": "NMTSat", 107 | "nationality": "United States", 108 | "configuration": "CubeSat", 109 | "type": ["Technology", "Magnetospheric Research"], 110 | "customer_name": "NASA", 111 | "manufacturer": "New Mexico Institute of Mining and Technology", 112 | "mass_kg": 4, 113 | "orbit": "LEO" 114 | }, 115 | { 116 | "norad_id": null, 117 | "name": "RSat", 118 | "nationality": "United States", 119 | "configuration": "CubeSat", 120 | "type": ["Technology"], 121 | "customer_name": "NASA", 122 | "manufacturer": "United States Naval Academy", 123 | "mass_kg": null, 124 | "orbit": "LEO" 125 | }, 126 | { 127 | "norad_id": null, 128 | "name": "Shields-1", 129 | "nationality": "United States", 130 | "configuration": "CubeSat", 131 | "type": ["Technology"], 132 | "customer_name": "NASA", 133 | "manufacturer": "NASA Langley Research Center", 134 | "mass_kg": null, 135 | "orbit": "LEO" 136 | }, 137 | { 138 | "norad_id": 43852, 139 | "name": "STF-1", 140 | "nationality": "United States", 141 | "configuration": "CubeSat", 142 | "type": ["Technology"], 143 | "customer_name": "NASA", 144 | "manufacturer": "West Virginia University / NASA IV&V", 145 | "mass_kg": 4, 146 | "orbit": "LEO" 147 | } 148 | ] 149 | }, 150 | "telemetry": null, 151 | "launch_site": { 152 | "name": "Mahia LC-1", 153 | "name_long": "Rocket Lab Launch Complex 1" 154 | }, 155 | "launch_success": true, 156 | "links": { 157 | "articles": [ 158 | "https://www.nasa.gov/content/upcoming-elana-cubesat-launches", 159 | "https://www.rocketlabusa.com/news/updates/rocket-lab-successfully-launches-nasa-cubesats-to-orbit-on-first-ever-venture-class-launch-services-mission/", 160 | "https://www.rocketlabusa.com/assets/Uploads/NASA-ELANA19-Presskit-December2019.pdf" 161 | ], 162 | "videos": [ 163 | "https://www.youtube.com/watch?v=CebXCobtIgc", 164 | "https://www.youtube.com/watch?v=F7Kr3664hJs" 165 | ], 166 | "mission_patch": { 167 | "original": "https://images2.imgbox.com/a8/ab/IhwIB4WV_o.png", 168 | "small": "https://images2.imgbox.com/90/ad/dmLQd3cD_o.png" 169 | } 170 | }, 171 | "details": "The Launch Services Program (LSP) at NASA's Kennedy Space Center in Florida manages a fun and unique program known as Educational Launch of Nanosatellites or ELaNa. This program enables students in the Science, Technology, Engineering and Mathematics fields to work directly with Nanosatellites and NASA. The students are involved in all aspects of the process from Development to Assembly and testing. CubeSats are small 10x10x10 CM (About 4 Inche Cube) satellites that can do a multitude of tasks once they are released in space. These ELaNa missions are the first Educational Cargo to be carried on launch vehicles for LSP." 172 | } 173 | 174 | ``` 175 | 176 | ## Contributions 177 | See the [contribution](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/CONTRIBUTING.md) guide for detailed steps 178 | 179 | ## Documentation 180 | See the `v1 documentation` [here](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1) 181 | 182 | ## Local Development 183 | Follow the quick guide [here](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/development.md) 184 | 185 | ## Technical Details 186 | * Deployed on [▲ZEIT](https://zeit.co/) 187 | * Using [Node.js](https://nodejs.org/en/) with the [Express](https://expressjs.com/) framework 188 | * Using [Jest](https://facebook.github.io/jest/) and [Supertest](https://github.com/visionmedia/supertest) for tests 189 | * All data stored in a [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) 3 node replica set cluster 190 | * Latest database with MongoDB collections in JSON files available [here](https://drive.google.com/file/d/1Cpn0DpeKrPz-wyjKqkVL82qBb1zj9BYK/view) 191 | 192 | ## FAQ's 193 | * If you have any questions or corrections, please open an issue and we'll get it merged ASAP 194 | * All data and photos are property of [ROCKET LAB USA](https://www.rocketlabusa.com/) 195 | * I am not affiliated with Rocket Lab in any way, shape, form, or fashion. Just a fun side project for me 196 | * For any other questions or concerns, just shoot me an email 197 | * Yes, this project is inspired by [SpaceX-API](https://github.com/r-spacex/SpaceX-API/) 198 | 199 | ## License 200 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fbarrosfilipe%2FRocket-Lab-API.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fbarrosfilipe%2FRocket-Lab-API?ref=badge_large) 201 | -------------------------------------------------------------------------------- /docs/development.md: -------------------------------------------------------------------------------- 1 | 1. Clone the repo 2 | ```bash 3 | git clone https://github.com/barrosfilipe/Rocket-Lab-API.git && cd Rocket-Lab-API 4 | ``` 5 | 6 | 2. Install dependencies 7 | ```bash 8 | yarn 9 | ``` 10 | 11 | 3. Run tests 12 | ```bash 13 | yarn test 14 | ``` 15 | 16 | 4. Start the app 17 | ```bash 18 | yarn dev 19 | ``` -------------------------------------------------------------------------------- /docs/v1/README.md: -------------------------------------------------------------------------------- 1 | ## API v1 Documentation 2 | This collection of documents describes the resources and functions that make up the Rocket Lab API. 3 | 4 | ## Authentication 5 | No authentication is required to use this public API 6 | 7 | ## Privacy 8 | We do not log IP addresses or any personally identifiable information at the app or web server level. We collect timestamps, 9 | HTTP methods, urls, and response times to adjust possible strategies on popular endpoints. Below is a sample log output: 10 | ```bash 11 | [23/Nov/2018:12:04:28 +0000] "GET /v1/launches/latest HTTP/1.1 200 - 39.082 ms" 12 | ``` 13 | ## Rate Limiting 14 | There's no known API rate limit. We are able to scale up to 10 max [▲ZEIT](https://zeit.co/) instances. 15 | 16 | ## Development Status 17 | Check it out [here](https://trello.com/b/6zQjMaff) 18 | 19 | ## API v1 Endpoints 20 | 21 | * Info - [/v1/info](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/info.md) 22 | 23 | * Launches - [/v1/launches](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/launches.md) 24 | 25 | * Payloads - [/v1/payloads](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/payloads.md) 26 | 27 | * Rockets [/v1/rockets](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/rockets.md) -------------------------------------------------------------------------------- /docs/v1/info.md: -------------------------------------------------------------------------------- 1 | # API v1 Info Resource 2 | Endpoints allowing you to get information related to Rocket Lab API. 3 | 4 | Info 5 | | [Launches](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/launches.md) 6 | | [Payloads](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/payloads.md) 7 | | [Rockets](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/rockets.md) 8 | 9 | ## Info Base Path 10 | [https://rocketlab-api.now.sh/v1](https://rocketlab-api.now.sh/v1) 11 | 12 | ## Info `GET /v1` 13 | * Expected HTTP **status code** `200 OK` 14 | * Expected **Content-Type** `application/json` 15 | * Expected **Body**: `↴` 16 | ```json 17 | { 18 | "name": "Rocket-Lab-API", 19 | "version": "1.0.0", 20 | "description": "An Open Source REST API for rocket, pad and launch data", 21 | "github": "https://github.com/barrosfilipe/Rocket-Lab-API", 22 | "author": "Filipe Barros ", 23 | "license": "MIT" 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/v1/launches.md: -------------------------------------------------------------------------------- 1 | # API v1 Launches Resource 2 | Endpoints allowing you to get information related to Rocket Lab launches. 3 | 4 | [Info](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/info.md) 5 | | Launches | [Payloads](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/payloads.md) 6 | | [Rockets](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/rockets.md) 7 | 8 | ## Launches Base Path 9 | [https://rocketlab-api.now.sh/v1/launches](https://rocketlab-api.now.sh/v1/launches) 10 | 11 | ## All Launches `GET /v1/launches` 12 | * Expected HTTP **status code** `200 OK` 13 | * Expected **Content-Type** `application/json` 14 | * Expected **Body**: `↴` 15 | ```json 16 | [{"flight_number": 1, "mission_name": "It's a Test", "upcoming": false, "..."}, "..."] 17 | ``` 18 | 19 | ## Latest Launch `GET /v1/launches/latest` 20 | * Expected HTTP **status code** `200 OK` 21 | * Expected **Content-Type** `application/json` 22 | * Expected **Body**: `↴` 23 | ```json 24 | {"flight_number": 3, "mission_name": "It's Business Time", "upcoming": false, "..."} 25 | ``` 26 | 27 | ## Next Launch `GET /v1/launches/next` 28 | * Expected HTTP **status code** `200 OK` 29 | * Expected **Content-Type** `application/json` 30 | * Expected **Body**: `↴` 31 | ```json 32 | {"flight_number": 4, "mission_name": "ELaNa 19", "upcoming": true, "..."} 33 | ``` 34 | 35 | ## Past Launches `GET /v1/launches/past` 36 | * Expected HTTP **status code** `200 OK` 37 | * Expected **Content-Type** `application/json` 38 | * Expected **Body**: `↴` 39 | ```json 40 | [{"flight_number": 1, "mission_name": "It's a Test", "upcoming": false, "..."}, "..."] 41 | ``` 42 | 43 | ## Upcoming Launches `GET /v1/launches/upcoming` 44 | * Expected HTTP **status code** `200 OK` 45 | * Expected **Content-Type** `application/json` 46 | * Expected **Body**: `↴` 47 | ```json 48 | [{"flight_number": 4, "mission_name": "ELaNa 19", "upcoming": true, "..."}, "..."] 49 | ``` 50 | 51 | ## One Launch by `flight_number` `GET /v1/launches/2` 52 | * Expected HTTP **status code** `200 OK` 53 | * Expected **Content-Type** `application/json` 54 | * Expected **Body**: `↴` 55 | ```json 56 | {"flight_number": 2, "mission_name": "Still Testing", "upcoming": false, "..."} 57 | ``` 58 | -------------------------------------------------------------------------------- /docs/v1/payloads.md: -------------------------------------------------------------------------------- 1 | # API v1 Payloads Resource 2 | Endpoints allowing you to get information related to Rocket Lab payloads. 3 | 4 | [Info](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/info.md) 5 | | [Launches](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/launches.md) 6 | | Payloads | [Rockets](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/rockets.md) 7 | 8 | ## Payloads Base Path 9 | [https://rocketlab-api.now.sh/v1/payloads](https://rocketlab-api.now.sh/v1/payloads) 10 | 11 | ## All Payloads `GET /v1/payloads` 12 | * Expected HTTP **status code** `200 OK` 13 | * Expected **Content-Type** `application/json` 14 | * Expected **Body**: `↴` 15 | ```json 16 | [ 17 | { 18 | "norad_id": 43163, 19 | "name": "Dove Pioneer", 20 | "nationality": "United States", 21 | "configuration": "CubeSat", 22 | "type": [ 23 | "Earth observation" 24 | ], 25 | "customer_name": "Planet Labs", 26 | "manufacturer": "Planet Labs", 27 | "mass_kg": 5, 28 | "orbit": "LEO" 29 | } 30 | ] 31 | ``` 32 | 33 | ## One Payloads by `name` `GET /v1/payloads/Proxima 1` 34 | * Expected HTTP **status code** `200 OK` 35 | * Expected **Content-Type** `application/json` 36 | * Expected **Body**: `↴` 37 | ```json 38 | [ 39 | { 40 | "norad_id": null, 41 | "name": "Proxima 1", 42 | "nationality": "United States", 43 | "configuration": "CubeSat", 44 | "type": [ 45 | "Communication", 46 | "IoT" 47 | ], 48 | "customer_name": "Fleet Space Technologies", 49 | "manufacturer": "Pumpkin Space Systems", 50 | "mass_kg": null, 51 | "orbit": "LEO" 52 | } 53 | ] 54 | ``` 55 | -------------------------------------------------------------------------------- /docs/v1/rockets.md: -------------------------------------------------------------------------------- 1 | # API v1 Rockets Resource 2 | Endpoints allowing you to get information related to Rocket Lab rockets. 3 | 4 | [Info](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/info.md) 5 | | [Launches](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/launches.md) 6 | | [Payloads](https://github.com/barrosfilipe/Rocket-Lab-API/blob/master/docs/v1/payloads.md) | Rockets 7 | 8 | ## Rockets Base Path 9 | [https://rocketlab-api.now.sh/v1/rockets](https://rocketlab-api.now.sh/v1/rockets) 10 | 11 | ## All Rockets `GET /v1/rockets` 12 | * Expected HTTP **status code** `200 OK` 13 | * Expected **Content-Type** `application/json` 14 | * Expected **Body**: `↴` 15 | ```json 16 | [{"id": 1, "name": "Electron", "active": true, "cost_currency": "U.S. dollar", "..."}, "..."] 17 | ``` 18 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rocket-lab-api", 3 | "version": "1.0.0", 4 | "description": "An Open Source REST API for rocket, pad, and launch data", 5 | "main": "./src/app.js", 6 | "scripts": { 7 | "start": "node src/app.js", 8 | "dev": "nodemon src/app.js", 9 | "test": "jest -i --forceExit" 10 | }, 11 | "repository": "https://github.com/barrosfilipe/Rocket-Lab-API.git", 12 | "keywords": [ 13 | "rocket-lab", 14 | "space", 15 | "rocket", 16 | "rest-api" 17 | ], 18 | "author": "Filipe Barros ", 19 | "license": "MIT", 20 | "dependencies": { 21 | "compression": "^1.7.3", 22 | "cors": "^2.8.5", 23 | "express": "^4.16.4", 24 | "helmet": "^3.15.0", 25 | "http-errors": "^1.7.1", 26 | "mongodb": "^3.1.9", 27 | "morgan": "^1.9.1", 28 | "response-time": "^2.3.2" 29 | }, 30 | "devDependencies": { 31 | "jest": "^24.8.0", 32 | "nodemon": "^1.18.6", 33 | "prettier": "^1.15.2", 34 | "prettierrc": "^0.0.0-5", 35 | "supertest": "^4.0.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const cors = require('cors'); 3 | const helmet = require('helmet'); 4 | const compression = require('compression'); 5 | const responseTime = require('response-time'); 6 | const createError = require('http-errors'); 7 | const morgan = require('morgan'); 8 | const MongoClient = require('mongodb'); 9 | const app = express(); 10 | 11 | /* Production read-only mongoDB */ 12 | const url = 13 | process.env.MONGO_URL || 14 | 'mongodb+srv://public:rocketlab@rocketlab-zkfvv.gcp.mongodb.net/rocketlab-api'; 15 | 16 | /* Import routes */ 17 | const routes_v1 = require('./routes/v1'); 18 | 19 | /* App logs */ 20 | if (process.env.NODE_ENV !== 'test') { 21 | app.use( 22 | morgan( 23 | '[:date[clf]] ":method :url HTTP/:http-version :status - :response-time ms"' 24 | ) 25 | ); 26 | } 27 | 28 | /* HTTP enhancements */ 29 | app.use(cors()); 30 | app.use(compression()); 31 | app.use(helmet()); 32 | app.use(responseTime()); 33 | 34 | /* Use routes */ 35 | app.use('/v1', routes_v1); 36 | 37 | /* Catch 404 and forward to error handler */ 38 | app.use((req, res, next) => { 39 | next(createError(404)); 40 | }); 41 | 42 | /* Error handler */ 43 | app.use((err, req, res, next) => { 44 | res.status(err.status || 500); 45 | res.json({ error: 'No results found' }); 46 | }); 47 | 48 | /* MongoDB Connection and Server Initialization */ 49 | (async () => { 50 | try { 51 | const client = await MongoClient.connect( 52 | url, 53 | { poolSize: 20, useNewUrlParser: true } 54 | ); 55 | 56 | global.db = client.db('rocketlab-api'); 57 | 58 | const port = process.env.PORT || 3000; 59 | app.listen(port, () => { 60 | app.emit('ready'); 61 | console.log(`Rocket Lab API is Running on Port ${port}`); 62 | }); 63 | } catch (err) { 64 | console.log(err.stack); 65 | } 66 | })(); 67 | 68 | module.exports = app; 69 | -------------------------------------------------------------------------------- /src/controllers/v1/info.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | index: async (req, res) => { 3 | const data = await global.db 4 | .collection('info') 5 | .find({}) 6 | .project({ _id: 0 }) 7 | .toArray(); 8 | 9 | res.json(data[0]); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/controllers/v1/launches.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | latest: async (req, res) => { 3 | const data = await global.db 4 | .collection('launches') 5 | .find({ upcoming: false }) 6 | .project({ _id: 0 }) 7 | .sort({ flight_number: -1 }) 8 | .limit(1) 9 | .toArray(); 10 | 11 | res.json(data[0]); 12 | }, 13 | 14 | all: async (req, res) => { 15 | const data = await global.db 16 | .collection('launches') 17 | .find({}) 18 | .project({ _id: 0 }) 19 | .toArray(); 20 | 21 | res.json(data); 22 | }, 23 | 24 | one: async (req, res) => { 25 | const data = await global.db 26 | .collection('launches') 27 | .find({ flight_number: parseInt(req.params.flight_number, 10) }) 28 | .project({ _id: 0 }) 29 | .toArray(); 30 | 31 | if (data.length === 0) { 32 | res.status(404).json({ error: 'Not found' }); 33 | return; 34 | } 35 | 36 | res.json(data[0]); 37 | }, 38 | 39 | upcoming: async (req, res) => { 40 | const data = await global.db 41 | .collection('launches') 42 | .find({ upcoming: true }) 43 | .project({ _id: 0 }) 44 | .toArray(); 45 | 46 | res.json(data); 47 | }, 48 | 49 | next: async (req, res) => { 50 | const data = await global.db 51 | .collection('launches') 52 | .find({ upcoming: true }) 53 | .project({ _id: 0 }) 54 | .sort({ flight_number: -1 }) 55 | .limit(1) 56 | .toArray(); 57 | 58 | res.json(data[0]); 59 | }, 60 | 61 | past: async (req, res) => { 62 | const data = await global.db 63 | .collection('launches') 64 | .find({ upcoming: false }) 65 | .project({ _id: 0 }) 66 | .toArray(); 67 | 68 | res.json(data); 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /src/controllers/v1/payloads.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | all: async (req, res) => { 3 | const data = await global.db 4 | .collection('payloads') 5 | .find({}) 6 | .project({ _id: 0 }) 7 | .toArray(); 8 | 9 | res.json(data); 10 | }, 11 | 12 | one: async (req, res) => { 13 | const data = await global.db 14 | .collection('payloads') 15 | .find({ name: req.params.name }) 16 | .project({ _id: 0 }) 17 | .limit(1) 18 | .toArray(); 19 | 20 | if (data.length === 0) { 21 | res.status(404).json({ error: 'Not found' }); 22 | return; 23 | } 24 | 25 | res.json(data[0]); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /src/controllers/v1/rockets.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | all: async (req, res) => { 3 | const data = await global.db 4 | .collection('rockets') 5 | .find({}) 6 | .project({ _id: 0 }) 7 | .toArray(); 8 | 9 | res.json(data); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/routes/v1.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const v1 = express.Router(); 3 | 4 | /* Controllers */ 5 | const info = require('../controllers/v1/info'); 6 | const launches = require('../controllers/v1/launches'); 7 | const payloads = require('../controllers/v1/payloads'); 8 | const rockets = require('../controllers/v1/rockets'); 9 | 10 | /* Info routes */ 11 | v1.get('/', info.index); 12 | 13 | /* Rocket routes */ 14 | v1.get('/rockets', rockets.all); 15 | 16 | /* Launch routes */ 17 | v1.get('/launches', launches.all); 18 | v1.get('/launches/latest', launches.latest); 19 | v1.get('/launches/past', launches.past); 20 | v1.get('/launches/next', launches.next); 21 | v1.get('/launches/upcoming', launches.upcoming); 22 | v1.get('/launches/:flight_number', launches.one); 23 | 24 | /* Payload routes */ 25 | v1.get('/payloads', payloads.all); 26 | v1.get('/payloads/:name', payloads.one); 27 | 28 | module.exports = v1; 29 | -------------------------------------------------------------------------------- /test/routes/v1.test.js: -------------------------------------------------------------------------------- 1 | const request = require('supertest'), 2 | app = require('../../src/app'); 3 | 4 | beforeAll(done => { 5 | app.on('ready', () => { 6 | done(); 7 | }); 8 | }); 9 | 10 | test('It should return project info', async () => { 11 | const response = await request(app).get('/v1'); 12 | expect(response.statusCode).toBe(200); 13 | expect(response.body).toEqual({ 14 | name: 'Rocket-Lab-API', 15 | version: '1.0.0', 16 | description: 'An Open Source REST API for rocket, pad and launch data', 17 | github: 'https://github.com/barrosfilipe/Rocket-Lab-API', 18 | author: 'Filipe Barros ', 19 | license: 'MIT' 20 | }); 21 | }); 22 | 23 | /* TODO */ 24 | 25 | test('It should return all launches', async () => { 26 | const response = await request(app).get('/v1/launches'); 27 | expect(response.statusCode).toBe(200); 28 | }); 29 | 30 | test('It should return latest launch', async () => { 31 | const response = await request(app).get('/v1/launches/latest'); 32 | expect(response.statusCode).toBe(200); 33 | }); 34 | 35 | test('It should return one launch', async () => { 36 | const response = await request(app).get('/v1/launches/1'); 37 | expect(response.statusCode).toBe(200); 38 | }); 39 | --------------------------------------------------------------------------------