1 | # Panda Sky
|
2 |
|
3 | _Quicky publish severless APIs to AWS._
|
4 |
|
5 | ## Install
|
6 | Install `panda-sky` as a global package, granting you access to the `sky`
|
7 | executable.
|
8 |
|
9 | npm install -g panda-sky
|
10 |
|
11 | Make sure you have an AWS account, and that you store your credentials at
|
12 | `~/.aws/credentials`.
|
13 | > If you don't have an Amazon Web Services (AWS) account currently, stop here,
|
14 | go [signup and get CLI access credentials](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-set-up.html)
|
15 | and then come back here.
|
16 |
|
17 | ## Quick Start
|
18 | These commands will take you from start to functioning deployment that you can
|
19 | iterate on.
|
20 |
|
21 | mkdir hello-sky && cd hello-sky
|
22 | npm init
|
23 | sky init
|
24 | sky build
|
25 | sky publish staging
|
26 |
|
27 | In about 60 seconds, you will see a message like this:
|
28 | > Your API is online and ready at the following endpoint:
|
29 | > https://<API-ID>.execute-api.us-west-2.amazonaws.com/staging
|
30 |
|
31 | If you direct your browser to
|
32 | https://<API-ID>.execute-api.us-west-2.amazonaws.com/staging/greeting/World, you will
|
33 | see the test message from the API you just deployed. Adding your name to the
|
34 | URL path will change the page, a simple demonstration dynamic behavior.
|
35 |
|
36 | You can also view a description of the API by directing a request against the API
|
37 | root, https://<API-ID>.execute-api.us-west-2.amazonaws.com/staging
|
38 |
|
39 | ## What Panda Sky Does
|
40 | This is a slightly more detailed walkthrough that includes how to give your application a custom domain and have Panda Sky setup the Route53 routing on your behalf.
|
41 |
|
42 | ### Initialize your app.
|
43 |
|
44 | mkdir greeting-api && cd greeting-api
|
45 | npm init
|
46 | sky init
|
47 |
|
48 | Panda Sky needs a `package.json` to anchor your project's dependencies when it gathers them and sends them to AWS to be used within a Lambda. `sky init` gives you the starter files for a project.
|
49 |
|
50 | ### Define your API.
|
51 |
|
52 | Edit your `api.yaml`. This file is the authoritative description of your API. Panda Sky uses it to build an API within the API Gateway platform. Each method is mapped to a corresponding Lambda that gets invoked when the method's handler recieves an HTTP request.
|
53 |
|
54 | ```yaml
|
55 | resources:
|
56 |
|
57 | greeting:
|
58 |
|
59 | path: "/greeting/{name}"
|
60 | description: Returns a greeting for {name}.
|
61 |
|
62 | methods:
|
63 |
|
64 | get:
|
65 | method: GET
|
66 | signature:
|
67 | status: 200
|
68 | accept: text/html
|
69 | ```
|
70 |
|
71 | ### Define a handler.
|
72 |
|
73 | Add a JavaScript file under `src/sky.js`:
|
74 |
|
75 | Lambdas execute Javascript code compatible with Node 6.10. Lambdas accept context
|
76 | from the corresponding Gateway method's HTTP request. After executing arbitrary
|
77 | code, the result is returned in the callback and sent as the response in the
|
78 | Gateway method.
|
79 |
|
80 | The code snippet below shows a section of the template code `sky init` drops
|
81 | into your repo. This method is invoked when the `GET` method is used in a
|
82 | request against the `greeting` resource. Edits here affect the API's response.
|
83 |
|
84 | ```javascript
|
85 | API[`${fullName}-greeting-get`] = async( function*(data, context, callback) {
|
86 | var message, name;
|
87 | name = data.name || "World";
|
88 | message = `<h1>Hello, ${name}!</h1>`;
|
89 | message += "<p>Seeing this page indicates a successful deployment of your test API with Panda Sky!</p>";
|
90 | return callback(null, message);
|
91 | });
|
92 | ```
|
93 |
|
94 | ### Environmental Variables
|
95 | Panda Sky supports the injection of environmental variables into your Lambda's context. These can be accessed from the `process` Node variable.
|
96 |
|
97 | > Currently within api.yaml, however this may be moved into sky.yaml so they can be set on a per-environment basis.
|
98 | ```yaml
|
99 | variables:
|
100 | foobar: This optional value is injected into the Lambda context
|
101 | ```
|
102 | > sky.js
|
103 | ```javascript
|
104 | var {foobar} = process.env;
|
105 | ```
|
106 |
|
107 | ## Built-in Helpers
|
108 | Panda Sky comes with helpers to ease development within a Lambda environment:
|
109 | ```coffeescript
|
110 | # Import Panda Sky Helpers
|
111 | {response, s3} = require "panda-sky-helpers"
|
112 | ```
|
113 |
|
114 | ### s3
|
115 | - `s3` is a wrapper around the AWS SDK library for S3.
|
116 |
|
117 | ```coffeescript
|
118 | {get, put, del} = s3 BucketName
|
119 | data = yield get "foobar.yaml"
|
120 | ```
|
121 |
|
122 | The `get`, `put`, and `del` methods do what they say. They are promises you can either chain `.then` or use ES6's yield / generator construct with. They are very thin wrappers, either succeeding or returning an error directly from the AWS library.
|
123 |
|
124 | ### response
|
125 | To invoke a given response within a Lambda, use the response class from Panda Sky
|
126 | ```coffeescript
|
127 | # Import Panda Sky Helpers
|
128 | {response} = require "panda-sky"
|
129 | new response.NotFound("Unable to locate the blog post in the database")
|
130 | new response.Unauthorized("You must login to access this resource")
|
131 | new response.ServiceUnavailable("Try again in 30 minutes")
|
132 | ```
|
133 |
|
134 | It takes the form:
|
135 | ```
|
136 | new response.<Response Type>(<Optional message>)
|
137 | ```
|
138 |
|
139 | > Note that responses must be explicitly definied within the API description.
|
140 |
|
141 |
|
142 |
|
143 | ## Custom Domains
|
144 |
|
145 | In order to publish your API to production, you need a domain to publish it to.
|
146 | [You need to tell AWS about it and acquire an SSL (TLS) cert][domain-setup].
|
147 |
|
148 | [domain-setup]:https://www.pandastrike.com/open-source/haiku9/publish/aws-setup
|
149 |
|
150 | ### Add The Domain To Your Configuration
|
151 |
|
152 | Add the name of your API and the domain to your `sky.yaml` file:
|
153 |
|
154 | This file tracks the overall configuration for your app. Panda Sky divides
|
155 | configuration between "environments" to group related config within one cli
|
156 | target. It allows you to switch your environment target without repeatedly
|
157 | editing this file.
|
158 |
|
159 | The `cache` stanza holds configuration for CloudFront distributions, which
|
160 | provides both edge caching for your API responses and custom domain assignment.
|
161 | Please note that setting up a distribution is time-intensive. It can take 15-30
|
162 | minutes to setup and sync your allocation across AWS's global constellation of
|
163 | edge servers.
|
164 |
|
165 | ```yaml
|
166 | name: greeting
|
167 | description: Greeting API
|
168 | aws:
|
169 | runtime: nodejs6.10
|
170 | domain:
|
171 | - greeting.com
|
172 | region: us-west-2
|
173 | environments:
|
174 |
|
175 | staging:
|
176 | hostnames:
|
177 | - staging-api
|
178 |
|
179 | production:
|
180 | hostnames:
|
181 | - api
|
182 | cache:
|
183 | expires: 1800
|
184 | priceClass: 100
|
185 | ```
|
186 |
|
187 | ### Publish Your API
|
188 |
|
189 | Publish your lambdas and their associated Gateway.
|
190 |
|
191 | sky publish staging
|
192 |
|
193 | ### Publish Your Custom Domain
|
194 |
|
195 | Your environment's custom domain is treated as a
|
196 | seperate resource. Publishing it will take a while
|
197 | (~30 minutes), but Sky (and AWS) are doing a
|
198 | lot for you. In addition to a custom domain with
|
199 | TLS termination, CloudFront is synchronizing
|
200 | an edge cache among servers deployed across
|
201 | the planet.
|
202 |
|
203 | ### Test It Out
|
204 |
|
205 | curl https://staging-api.greeting.com/greeting/Ace
|
206 | Hello, Ace!
|
207 |
|
208 | ## Status
|
209 |
|
210 | Panda Sky is in beta.
|
211 |
|