more tutorial

This commit is contained in:
Chad Arimura
2017-05-25 14:31:22 -07:00
parent a565c09c7f
commit f97ac83255
37 changed files with 515 additions and 2 deletions

View File

@@ -4,4 +4,4 @@ This directory has a collection of example functions you can look at to learn mo
## Tutorial Series
The [Tutorial Series](tutorial/) will demonstrate some of Oracle Functions capabilities through a series of exmaples. We'll try to examples in most major languages. This is a great place to start!
The [Tutorial Series](tutorial/) will demonstrate some of Oracle Functions capabilities through a series of exmaples. We'll try to show examples in most major languages. This is a great place to start!

7
examples/tutorial/hello/go/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
vendor/
/hello
/go
/app
/__uberscript__
func.yaml

View File

@@ -0,0 +1,56 @@
# Tutorial 1: Go Function w/ Input (3 minutes)
This example will show you how to test and deploy Go (Golang) code to Oracle Functions. It will also demonstrate passing data in through stdin.
First, run the following commands to create, run, and deploy your function:
```sh
# Initialize your function creating a func.yaml file
fn init <DOCKERHUB_USERNAME>/hello
# Test your function. This will run inside a container exactly how it will on the server
fn run
# Now try with an input
cat hello.payload.json | fn run
# Deploy your functions to the Oracle Functions server (default localhost:8080)
# This will create a route to your function as well
fn deploy myapp
```
Now call your function:
```sh
curl http://localhost:8080/r/myapp/hello
```
Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello)
And now with the JSON input:
```sh
curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello
```
That's it!
# In Review
1. We piped JSON data into the function at the command line
```sh
cat hello.payload.json | fn run
```
2. We received our input through stdin
```go
json.NewDecoder(os.Stdin).Decode(p)
```
3. We wrote our output to stdout
```go
fmt.Printf("Hello")
```
4. We sent stderr to the server logs
```go
log.Println("here")
```
# Next Up
## [Tutorial 2: Input Parameters](examples/tutorial/params)

View File

@@ -0,0 +1,20 @@
package main
import (
"encoding/json"
"fmt"
"log"
"os"
)
type Person struct {
Name string
}
func main() {
p := &Person{Name: "World"}
json.NewDecoder(os.Stdin).Decode(p)
fmt.Printf("Hello %v!\n", p.Name)
log.Println("---> stderr goes to the server logs.")
}

View File

@@ -0,0 +1,3 @@
{
"name": "Johnny"
}

View File

@@ -0,0 +1,3 @@
node_modules/
func.yaml
Dockerfile

View File

@@ -0,0 +1,41 @@
## Quick Example for a NodeJS Function (4 minutes)
This example will show you how to test and deploy a Node function to Oracle Functions.
```sh
# create your func.yaml file
fn init <YOUR_DOCKERHUB_USERNAME>/hello
# build the function
fn build
# test it
cat hello.payload.json | fn run
# push it to Docker Hub
fn push
# Create a route to this function on Oracle Functions
fn routes create myapp /hello
```
Now surf to: http://localhost:8080/r/myapp/hello
## Dependencies
Create a [package.json](https://docs.npmjs.com/getting-started/using-a-package.json) file in your functions directory.
Run:
```sh
docker run --rm -v "$PWD":/function -w /function funcy/node:dev npm install
```
Then everything should work.
For example, using the `package.json` file in this directory which includes the [request](https://www.npmjs.com/package/request) package, you can add this to func.js and it will work:
```js
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
})
```

View File

@@ -0,0 +1,9 @@
name = "World";
fs = require('fs');
try {
obj = JSON.parse(fs.readFileSync('/dev/stdin').toString())
if (obj.name != "") {
name = obj.name
}
} catch(e) {}
console.log("Hello", name, "from Node!");

View File

@@ -0,0 +1,3 @@
{
"name": "Johnny"
}

View File

@@ -0,0 +1,7 @@
{
"name": "my-awesome-func",
"version": "1.0.0",
"dependencies": {
"request": "^2.78.0"
}
}

View File

@@ -0,0 +1 @@
vendor/

View File

@@ -0,0 +1,6 @@
FROM funcy/php
WORKDIR /app
ADD . /app
ENTRYPOINT ["php", "hello.php"]

View File

@@ -0,0 +1,48 @@
## Quick Example for a PHP Function (4 minutes)
This example will show you how to test and deploy Go (Golang) code to Oracle Functions.
### 1. Prepare the `func.yaml` file:
At func.yaml you will find:
```yml
name: USERNAME/hello
version: 0.0.1
path: /hello
build:
- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install
```
The important step here is to ensure you replace `USERNAME` with your Docker Hub account name. Some points of note:
the application name is `phpapp` and the route for incoming requests is `/hello`. These informations are relevant for
the moment you try to test this function.
### 2. Build:
```sh
# build the function
fn build
# test it
cat hello.payload.json | fn run
# push it to Docker Hub
fn push
# Create a route to this function on Oracle Functions
fn routes create phpapp /hello
```
`-v` is optional, but it allows you to see how this function is being built.
### 3. Queue jobs for your function
Now you can start jobs on your function. Let's quickly queue up a job to try it out.
```sh
cat hello.payload.json | fn call phpapp /hello
```
Here's a curl example to show how easy it is to do in any language:
```sh
curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/phpapp/hello
```

View File

@@ -0,0 +1,4 @@
{
"require": {
}
}

View File

@@ -0,0 +1,5 @@
name: USERNAME/hello
version: 0.0.1
path: /hello
build:
- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install

View File

@@ -0,0 +1,3 @@
{
"name": "Johnny"
}

View File

@@ -0,0 +1,10 @@
<?php
require 'vendor/autoload.php';
stream_set_blocking(STDIN, 0);
$payload = json_decode(file_get_contents("php://stdin"), true);
if (isset($payload['name'])) {
echo "Hello ", $payload['name'],"!\n\n";
} else {
echo "Hello World!\n\n";
}

View File

@@ -0,0 +1,2 @@
packages/
func.yaml

View File

@@ -0,0 +1,6 @@
FROM funcy/python:2
WORKDIR /app
ADD . /app
ENTRYPOINT ["python", "hello.py"]

View File

@@ -0,0 +1,48 @@
## Quick Example for a Python Function (4 minutes)
This example will show you how to test and deploy Go (Golang) code to Oracle Functions.
### 1. Prepare the `func.yaml` file:
At func.yaml you will find:
```yml
name: USERNAME/hello
version: 0.0.1
path: /hello
build:
- docker run --rm -v "$PWD":/worker -w /worker funcy/python:2-dev pip install -t packages -r requirements.txt
```
The important step here is to ensure you replace `USERNAME` with your Docker Hub account name. Some points of note:
the application name is `pythonapp` and the route for incoming requests is `/hello`. These informations are relevant for
the moment you try to test this function.
### 2. Build:
```sh
# build the function
fn build
# test it
cat hello.payload.json | fn run
# push it to Docker Hub
fn push
# Create a route to this function on Oracle Functions
fn routes create pythonapp /hello
```
`-v` is optional, but it allows you to see how this function is being built.
### 3. Queue jobs for your function
Now you can start jobs on your function. Let's quickly queue up a job to try it out.
```sh
cat hello.payload.json | fn call pythonapp /hello
```
Here's a curl example to show how easy it is to do in any language:
```sh
curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/pythonapp/hello
```

View File

@@ -0,0 +1,3 @@
{
"name": "Johnny"
}

View File

@@ -0,0 +1,12 @@
import sys
sys.path.append("packages")
import os
import json
name = "World"
if not os.isatty(sys.stdin.fileno()):
obj = json.loads(sys.stdin.read())
if obj["name"] != "":
name = obj["name"]
print "Hello", name, "!!!"

View File

@@ -0,0 +1,5 @@
bundle/
.bundle/
func.yaml
Dockerfile
Gemfile.lock

View File

@@ -0,0 +1,4 @@
source 'https://rubygems.org'
gem 'httparty', '~> 0.14.0'
gem 'json', '> 1.8.2'

View File

@@ -0,0 +1,44 @@
## Quick Example for a Ruby Function (4 minutes)
This example will show you how to test and deploy a Ruby function to Oracle Functions.
```sh
# create your func.yaml file
fn init <YOUR_DOCKERHUB_USERNAME>/hello
# install dependencies, we need the json gem to run this
docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean
# build the function
fn build
# test it
cat hello.payload.json | fn run
# push it to Docker Hub
fn push
# Create a route to this function on Oracle Functions
fn routes create myapp /hello
```
Now surf to: http://localhost:8080/r/myapp/hello
## Dependencies
Create a [Gemfile](http://bundler.io/gemfile.html) file in your function directory, then run:
```sh
docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle install --standalone --clean
```
Ruby doesn't pick up the gems automatically, so you'll have to add this to the top of your `func.rb` file:
```ruby
require_relative 'bundle/bundler/setup'
```
Open `func.rb` to see it in action.
To update dependencies:
```sh
docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle update
# then install again to vendor them
docker run --rm -it -v ${pwd}:/worker -w /worker funcy/ruby:dev bundle update
```

View File

@@ -0,0 +1,12 @@
require_relative 'bundle/bundler/setup'
require 'json'
name = "World"
payload = STDIN.read
if payload != ""
payload = JSON.parse(payload)
name = payload['name']
end
puts "Hello #{name} from Ruby!"

View File

@@ -0,0 +1,3 @@
{
"name": "Johnny"
}

View File

@@ -0,0 +1,6 @@
[package]
name = "func"
version = "0.1.0"
authors = ["Seif Lotfy <seif@iron.io>"]
[dependencies]

View File

@@ -0,0 +1,33 @@
# Using rust with functions
The easiest way to create a function in rust is via ***cargo*** and ***fn***.
## Prerequisites
First create an epty rust project as follows:
```bash
cargo init --name func --bin
```
Make sure the project name is ***func*** and is of type ***bin***. Now just edit your code, once done you can create a function.
## Creating a function
Simply run
```bash
fn init --runtime=rust <username>/<funcname>
```
This will create the ```func.yaml``` file required by functions, which can be built by running:
```bash
fn build
```
## Testing
```bash
fn run
```

View File

@@ -0,0 +1,10 @@
use std::io;
use std::io::Read;
fn main() {
let mut buffer = String::new();
let stdin = io::stdin();
if stdin.lock().read_to_string(&mut buffer).is_ok() {
println!("Hello {}", buffer.trim());
}
}

View File

@@ -0,0 +1,45 @@
package main
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"net/http"
"os"
"strconv"
)
func main() {
for {
res := http.Response{
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
StatusCode: 200,
Status: "OK",
}
r := bufio.NewReader(os.Stdin)
req, err := http.ReadRequest(r)
var buf bytes.Buffer
if err != nil {
res.StatusCode = 500
res.Status = http.StatusText(res.StatusCode)
fmt.Fprintln(&buf, err)
} else {
l, _ := strconv.Atoi(req.Header.Get("Content-Length"))
p := make([]byte, l)
r.Read(p)
fmt.Fprintf(&buf, "Hello %s\n", p)
for k, vs := range req.Header {
fmt.Fprintf(&buf, "ENV: %s %#v\n", k, vs)
}
}
res.Body = ioutil.NopCloser(&buf)
res.ContentLength = int64(buf.Len())
res.Write(os.Stdout)
}
}

View File

@@ -0,0 +1,9 @@
{"route":{
"app_name": "myapp",
"path": "/hot",
"image": "USERNAME/hchttp",
"memory": 64,
"type": "sync",
"config": null,
"format": "http"
}}

View File

@@ -0,0 +1,7 @@
# Tutorial Series
1. [Tutorial 1](examples/tutorial/hello): Learn the basics about sending data into your function
2. [Tutorial 2](examples/tutorial/params): Learn how to get parameters from a web request
3. [Tutorial 3](examples/tutorial/hotfunctions): Write your first HotFunction (stays alive to minimze latency between requests)
4. [Tutorial 4](): TBD

View File

@@ -0,0 +1,30 @@
package main
import (
"fmt"
"log"
"net/url"
"os"
)
func main() {
s := os.Getenv("REQUEST_URL")
fmt.Printf("REQUEST_URL --> %v\n\n", s)
u, err := url.Parse(s)
if err != nil {
log.Fatal(err)
}
m, _ := url.ParseQuery(u.RawQuery)
if len(m) == 0 {
fmt.Println("Try adding some URL params like &id=123")
} else {
for k, v := range m {
fmt.Printf("found param: %v, val: %v\n", k, v[0])
}
}
}

View File

@@ -0,0 +1,6 @@
name: carimura2/fn3_request
version: 0.0.6
runtime: go
entrypoint: ./func
path: /fn3
max_concurrency: 1