diff --git a/api/agent/agent_test.go b/api/agent/agent_test.go index faff2f8e4..255dc07e4 100644 --- a/api/agent/agent_test.go +++ b/api/agent/agent_test.go @@ -66,7 +66,7 @@ func TestCallConfigurationRequest(t *testing.T) { req.Header.Add("MYREALHEADER", "FOOLORD") req.Header.Add("MYREALHEADER", "FOOPEASANT") req.Header.Add("Content-Length", contentLength) - req.Header.Add("FN_ROUTE", "thewrongroute") // ensures that this doesn't leak out, should be overwritten + req.Header.Add("FN_PATH", "thewrongroute") // ensures that this doesn't leak out, should be overwritten call, err := a.GetCall( WithWriter(w), // XXX (reed): order matters [for now] @@ -119,7 +119,7 @@ func TestCallConfigurationRequest(t *testing.T) { expectedBase := map[string]string{ "FN_FORMAT": format, "FN_APP_NAME": appName, - "FN_ROUTE": path, + "FN_PATH": path, "FN_MEMORY": strconv.Itoa(memory), "FN_TYPE": typ, "APP_VAR": "FOO", @@ -210,7 +210,7 @@ func TestCallConfigurationModel(t *testing.T) { env := map[string]string{ "FN_FORMAT": format, "FN_APP_NAME": appName, - "FN_ROUTE": path, + "FN_PATH": path, "FN_MEMORY": strconv.Itoa(memory), "FN_TYPE": typ, "APP_VAR": "FOO", diff --git a/api/agent/call.go b/api/agent/call.go index 3b811c919..14821e813 100644 --- a/api/agent/call.go +++ b/api/agent/call.go @@ -79,7 +79,8 @@ func FromRequest(appName, path string, req *http.Request) CallOpt { baseVars["FN_FORMAT"] = route.Format baseVars["FN_APP_NAME"] = appName - baseVars["FN_ROUTE"] = route.Path + baseVars["FN_PATH"] = route.Path + // TODO: might be a good idea to pass in: envVars["FN_BASE_PATH"] = fmt.Sprintf("/r/%s", appName) || "/" if using DNS entries per app baseVars["FN_MEMORY"] = fmt.Sprintf("%d", route.Memory) baseVars["FN_TYPE"] = route.Type @@ -188,7 +189,7 @@ func noOverrideVars(key string) bool { var overrideVars = map[string]bool{ "FN_FORMAT": true, "FN_APP_NAME": true, - "FN_ROUTE": true, + "FN_PATH": true, "FN_MEMORY": true, "FN_TYPE": true, "FN_CALL_ID": true, diff --git a/api/models/error.go b/api/models/error.go index c6a27a4dc..eb9b40350 100644 --- a/api/models/error.go +++ b/api/models/error.go @@ -154,7 +154,7 @@ var ( } ) -// any error that implements this interface will return an API response +// APIError any error that implements this interface will return an API response // with the provided status code and error message body type APIError interface { Code() int @@ -170,7 +170,7 @@ func (e err) Code() int { return e.code } func NewAPIError(code int, e error) APIError { return err{code, e} } -// uniform error output +// Error uniform error output type Error struct { Error *ErrorBody `json:"error,omitempty"` } diff --git a/docs/README.md b/docs/README.md index 6efde74eb..3c88959d0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,13 +8,15 @@ If you are a developer using Fn through the API, this section is for you. * [Usage](usage.md) * [Writing functions](writing.md) * [fn (CLI Tool)](https://github.com/fnproject/cli/blob/master/README.md) +* [Hot functions](hot-functions.md) +* [Async functions](async.md) +* [Organizing functions into an application](developers/apps.md) * [Function file (func.yaml)](function-file.md) * [Client Libraries](developers/clients.md) * [Packaging functions](packaging.md) * [Open Function Format](function-format.md) * API Reference (coming soon) -* [Hot functions](hot-functions.md) -* [Async functions](async.md) +* [Object Model](developers/model.md) * [FAQ](faq.md) ## For Operators diff --git a/docs/developers/apps.md b/docs/developers/apps.md new file mode 100644 index 000000000..634bcf710 --- /dev/null +++ b/docs/developers/apps.md @@ -0,0 +1,63 @@ +# Applications + +In `fn`, an application is a group of functions with path mappings (routes) to each function ([learn more](model.md)). +We've tried to make it easy to work with full applications by providing tools that work with all the applications functions. + +## Creating an Application + +All you have to do is create a file called `app.yaml` in your applications root directory, and the only required field is a name: + +```yaml +name: myawesomeapp +``` + +Once you have that file in place, the `fn` commands will work in the context of that application. + +## The Index Function (aka: Root Function) + +The root app directory can also contain a `func.yaml` which will be the function access at `/`. + +## Function paths + +By default, the function name and path will be the same as the directory structure. For instance, if you +have a structure like this: + +```txt +- app.yaml +- func.yaml +- func.go +- hello/ + - func.yaml + - func.js +- users/ + - func.yaml + - func.rb +``` + +The URL's to access those functions will be: + +``` +http://abc.io/ -> root function +http://abc.io/hello -> function in hello/ directory +http://abc.io/users -> function in users/ directory +``` + +## Deploying an entire app at once + +```sh +fn deploy --all +``` + +If you're just testing locally, you can speed it up with the `--local` flag. + +## Deploying a single function in the app + +To deploy the `hello` function only, from the root dir, run: + +```sh +fn deploy hello +``` + +## Example app + +See https://github.com/fnproject/fn/tree/master/examples/app for a simple example. diff --git a/docs/developers/model.md b/docs/developers/model.md new file mode 100644 index 000000000..46e50c6dc --- /dev/null +++ b/docs/developers/model.md @@ -0,0 +1,31 @@ +# Object Model + +This document describes the different objects we store and the relationships between them. + +## Applications + +At the root of everything are applications. In `fn`, an application is essentially a grouping of functions +with path mappings (routes) to each function. For instance, consider the following URLs for the app called `myapp`: + +``` +http://myapp.com/hello +http://myapp.com/users +``` + +This is an app with 2 routes: + +1. A mapping of the path `/hello` to a function called `hello` +1. A mapping of the path `/users` to a function called `users` + +## Routes + +An app consists of 1 or more routes. A route stores the mapping between URL paths and functions (ie: container iamges). + +## Calls + +A call represents an invocation of a function. Every request for a URL as defined in the routes, a call is created. +The `call_id` for each request will show up in all logs and the status of the call, as well as the logs, can be retrieved using the `call_id`. + +## Logs + +Logs are stored for each `call` that is made and can be retrieved with the `call_id`. diff --git a/docs/swagger.yml b/docs/swagger.yml index c22350f5f..23ae573b9 100644 --- a/docs/swagger.yml +++ b/docs/swagger.yml @@ -508,7 +508,7 @@ definitions: readOnly: true config: type: object - description: Application configuration + description: Application configuration, applied to all routes. additionalProperties: type: string diff --git a/docs/writing.md b/docs/writing.md index ed4b56ada..8ee61e56e 100644 --- a/docs/writing.md +++ b/docs/writing.md @@ -31,7 +31,7 @@ You will also have access to a set of environment variables. * `FN_REQUEST_URL` - the full URL for the request ([parsing example](https://github.com/fnproject/fn/tree/master/examples/tutorial/params)) * `FN_APP_NAME` - the name of the application that matched this route, eg: `myapp` -* `FN_ROUTE` - the matched route, eg: `/hello` +* `FN_PATH` - the matched route, eg: `/hello` * `FN_METHOD` - the HTTP method for the request, eg: `GET` or `POST` * `FN_CALL_ID` - a unique ID for each function execution. * `FN_FORMAT` - a string representing one of the [function formats](function-format.md), currently either `default` or `http`. Default is `default`. diff --git a/examples/app/README.md b/examples/app/README.md new file mode 100644 index 000000000..bb36b194c --- /dev/null +++ b/examples/app/README.md @@ -0,0 +1,5 @@ +# App Example + +This shows you how to organize functions into a full application and deploy them easily with one command. + +See [apps documentation](/docs/developers/app.md) for details on how to use this. diff --git a/examples/app/app.yaml b/examples/app/app.yaml new file mode 100644 index 000000000..0e1cba898 --- /dev/null +++ b/examples/app/app.yaml @@ -0,0 +1,3 @@ +name: helloapp +config: + foo: bar diff --git a/examples/app/footer/func.rb b/examples/app/footer/func.rb new file mode 100644 index 000000000..944ea9ccc --- /dev/null +++ b/examples/app/footer/func.rb @@ -0,0 +1,9 @@ +puts %{ +
+