apache / openwhisk

Apache OpenWhisk is an open source serverless cloud platform
https://openwhisk.apache.org/
Apache License 2.0
6.54k stars 1.17k forks source link

promote web actions to API v2 #1965

Closed rabbah closed 7 years ago

rabbah commented 7 years ago

This is an epic of proposed changes to promote web actions from experimental to a formal API. It will be part of version 2 of the API.

  1. [x] In line with normalization of the v2 path in this https://github.com/openwhisk/openwhisk/issues/219#issuecomment-272951007, the resource paths will adopt the fully qualified name format (/namespace/package/action, where "default" is used for the default package). The API will separate into CRUD operations (thus allowing us to reclaim the verb POST), an "activation" path for what is today action invocation (trigger firing) via POST, and "web" activations. For example (subject to revision):

    • /api/v2/actions/namespace/package/name for CRUD on actions with fully qualified name
    • /api/v2/web/namespace/package/name for web invoke
    • /api/v2/activate/namespace/package/name for what we currently call POST invoke (could use this for both trigger or action which might be a nice feature although requires type disambiguation in the backend).
      • For this issue, we are only concerned with a path for web actions e.g., /api/v1/web (or /api/v2/web).
  2. [x] make .http optional for web invoke and it is the default extension (when none is specified); preserve .json, .html, and .text as syntactic sugar for .http and possibly add .svg. The caveat when .http is omitted is that there is ambiguity when an action name might include a period.

  3. [x] add __ow_body for a request body that is neither JSON or form data (otherwise there is no such property and the contents are first class as done today).

  4. [x] remove meta from the __ow_* context variables (__meta_ow_headers -> __ow_headers and __meta_ow_path -> __ow_path).

  5. [x] rename code field from HTTP response to statusCode.

  6. [x] add X-OW-RAW-HTTP for web activations which always pass the request body via __ow_body instead of promoting the values to first class parameters. The query parameters are passed as part of the path.

  7. [x] add a new parameter/directive to expose web action instead of using a web-export annotation. open, public, and anonymous were considered, but no winner yet.

  8. [ ] the CLI shall provide the web action URL on demand.

From discussion with @mbehrendt @sjfink @nickm and @csantanapr. CC @dubeejw @mdeuser

rabbah commented 7 years ago

A comment on the "api-experimental" and API gateway. The plan is to separate that into an entirely self contained package and CLI plugin. The distinction between the API gateway and web actions reduces to:

  1. custom/control over mapping of paths (dont have to follow the openwhisk fully qualified naming)
  2. OAuth plugins
  3. custom throttling
  4. a general API mapping tool, of which some mapping is delegated to openwhisk
  5. it's a standalone service (include CLI tooling - or plugin for wsk cli)
csantanapr commented 7 years ago

@rabbah

Do we want to add the following to this Epic?

csantanapr commented 7 years ago

@rabbah

What about query parameters in path?

I want to be able to tell the controller that I want the raw URL path and query string in my web action. Do we use a new header raw?

I want to be able access __ow_path argument with a value of "/store/cats?color=black" meaning what ever is pass in URL don't touch it just pass it down This allows to easily build shim library that handles raw body, headers and URL/quey

If not inside my action I would need to exclude all the _ow* parameter and compose back the URL path and query params This will consume time in my webaction, and would not be able to construct the order of the query string

rabbah commented 7 years ago

Amended.

rabbah commented 7 years ago

iā€™m increasingly thinking the raw header mechanism to accept a raw body will not apply broadly to web actions: if one does not control the request, how does one add the required header?

this makes this feature not very useful as a web action (absent an api gw or some proxy). what if instead this was just another decorator on the the web action:

wsk action create httpExample req.js --web-action --raw-http
csantanapr commented 7 years ago

what if instead this was just another decorator on the the web action:

I'm fine with this option, I think it was on the table at one time during design discussions.

Then one more less thing to configure on apigw to be concern šŸ‘šŸ¼

csantanapr commented 7 years ago

Just for the record, another option on the table was using an extension on the URI I.e. "default/action.raw"

But Iike the decorator if I have to choose, maybe have .raw as a secondary way

cfjedimaster commented 7 years ago

Can you clarify if X-OW-RAW-HTTP means the RAW json body posted?

csantanapr commented 7 years ago

Yes

cfjedimaster commented 7 years ago

Thanks - I'm 99% sure this is blocking me from using it for Alexa in production. What is the rough ETA?

csantanapr commented 7 years ago

You have access to the body today as input parameters

Can you open an issue on what specific is your requirement?

Today you have access to the body as long is json and also all headers

csantanapr commented 7 years ago

Add any errors or sample code when you open the issue, also will serve as an use case for testing

cfjedimaster commented 7 years ago

Alexa requires you to verify the call they make to your action. As part of verification, you need the RAW string. Yes, OW parses it for us and gives us nice args. I tried to make a new string out of it, but if you don't match the exact same order of args they sent, it fails verification. So imagine the body was:

{"name":"ray", "age": }

When I get this in OW, I don't know that name was first and age was second. So if I rebuild the body by looping over args, I am not guaranteed to get the same string that was sent to me originally.

csantanapr commented 7 years ago

Yeah if they require you to verify the body payload as a hash like a sha1 then it will not match

cfjedimaster commented 7 years ago

Cool. So any rough ETA?

rabbah commented 7 years ago

It will be in GitHub Monday I'd expect.

cfjedimaster commented 7 years ago

Ok - another dumb question. :) If it is on GitHub Monday, when will it be available via Bluemix? (Ie, when can I use, blog it, etc. :)

rabbah commented 7 years ago

Separate question - ask in internal slack.

ddragosd commented 7 years ago

This reminds me of this conversation we had on the Apache DL when there was this idea that maybe OW shouldn't be so intrusive on the payload, but pass it "as-is" instead of decoding it. It looks like we got to that point; now I'm wondering if the plan is to still decode it and pass it twice: raw and decoded.

@cfjedimaster IIRC you also need the headers to check the signature. See - https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-an-alexa-skill-as-a-web-service#checking-the-signature-of-the-request . I don't recall reading that the Alexa SDK has support for this; I was actually thinking at implementing this in the Gateway for performance reasons.

akrabat commented 7 years ago

FWiW, the Request object specified by PHP's Framework Interopability Group passes to body twice like this with raw available via `getBody()' and the decoded version via 'getParsedBody()'.

cfjedimaster commented 7 years ago

@ddragosd Yep, I know. The only part I have missing is the raw body.

ddragosd commented 7 years ago

@akrabat I'm not familiar with PHP but I'd like to verify an assumption that the body is not actually passed twice, but it's only decoded on-demand via getParsedBody() method ?

akrabat commented 7 years ago

There are multiple libraries that implement the standard & so it depends on the implementation. It's more efficient to decode on first demand & cache the decoded result.

rabbah commented 7 years ago

The raw-http indicator (originally suggested as a header, but now implemented as an annotation on the action) will pass the body as a base64 encoded string to the action (if binary content). To pass it as a raw byte stream requires further changes in the controller/invoker interface (which i posit are not in scope for this issue). This gets closer to making the payload more opaque.