├── .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 | [](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 |
--------------------------------------------------------------------------------