From 35bcc4e65859190cb6444475f8bd4f71b65d82ab Mon Sep 17 00:00:00 2001 From: Travis Reeder Date: Fri, 29 Sep 2017 15:59:39 -0700 Subject: [PATCH] Blog API example (#377) --- examples/apps/blog/README.md | 34 +++++++++++++++++++ examples/apps/blog/app.yaml | 1 + examples/apps/blog/func.go | 22 ++++++++++++ examples/apps/blog/func.yaml | 5 +++ examples/apps/blog/post.json | 4 +++ examples/apps/blog/posts/Gemfile | 5 +++ examples/apps/blog/posts/create/Gemfile | 5 +++ examples/apps/blog/posts/create/func.rb | 20 +++++++++++ examples/apps/blog/posts/create/func.yaml | 5 +++ examples/apps/blog/posts/create/test.json | 26 ++++++++++++++ examples/apps/blog/posts/func.rb | 14 ++++++++ examples/apps/blog/posts/func.yaml | 5 +++ examples/apps/blog/posts/test.json | 26 ++++++++++++++ examples/apps/blog/schema/Gemfile | 5 +++ examples/apps/blog/schema/create.rb | 10 ++++++ examples/apps/blog/schema/func.yaml | 5 +++ examples/apps/blog/test.json | 26 ++++++++++++++ examples/{app => apps/hellos}/README.md | 0 examples/{app => apps/hellos}/app.yaml | 0 examples/{app => apps/hellos}/footer/func.rb | 0 .../{app => apps/hellos}/footer/func.yaml | 0 examples/{app => apps/hellos}/func.go | 0 examples/{app => apps/hellos}/func.yaml | 0 examples/{app => apps/hellos}/header/func.rb | 0 .../{app => apps/hellos}/header/func.yaml | 0 examples/{app => apps/hellos}/node/.gitignore | 0 examples/{app => apps/hellos}/node/README.md | 0 examples/{app => apps/hellos}/node/func.js | 0 examples/{app => apps/hellos}/node/func.yaml | 0 .../{app => apps/hellos}/node/package.json | 0 .../{app => apps/hellos}/python/.gitignore | 0 .../{app => apps/hellos}/python/README.md | 0 examples/{app => apps/hellos}/python/func.py | 0 .../{app => apps/hellos}/python/func.yaml | 0 examples/{app => apps/hellos}/ruby/.gitignore | 0 examples/{app => apps/hellos}/ruby/Gemfile | 0 examples/{app => apps/hellos}/ruby/README.md | 0 examples/{app => apps/hellos}/ruby/func.rb | 0 examples/{app => apps/hellos}/ruby/func.yaml | 0 39 files changed, 218 insertions(+) create mode 100644 examples/apps/blog/README.md create mode 100644 examples/apps/blog/app.yaml create mode 100644 examples/apps/blog/func.go create mode 100644 examples/apps/blog/func.yaml create mode 100644 examples/apps/blog/post.json create mode 100644 examples/apps/blog/posts/Gemfile create mode 100644 examples/apps/blog/posts/create/Gemfile create mode 100644 examples/apps/blog/posts/create/func.rb create mode 100644 examples/apps/blog/posts/create/func.yaml create mode 100644 examples/apps/blog/posts/create/test.json create mode 100644 examples/apps/blog/posts/func.rb create mode 100644 examples/apps/blog/posts/func.yaml create mode 100644 examples/apps/blog/posts/test.json create mode 100644 examples/apps/blog/schema/Gemfile create mode 100644 examples/apps/blog/schema/create.rb create mode 100644 examples/apps/blog/schema/func.yaml create mode 100644 examples/apps/blog/test.json rename examples/{app => apps/hellos}/README.md (100%) rename examples/{app => apps/hellos}/app.yaml (100%) rename examples/{app => apps/hellos}/footer/func.rb (100%) rename examples/{app => apps/hellos}/footer/func.yaml (100%) rename examples/{app => apps/hellos}/func.go (100%) rename examples/{app => apps/hellos}/func.yaml (100%) rename examples/{app => apps/hellos}/header/func.rb (100%) rename examples/{app => apps/hellos}/header/func.yaml (100%) rename examples/{app => apps/hellos}/node/.gitignore (100%) rename examples/{app => apps/hellos}/node/README.md (100%) rename examples/{app => apps/hellos}/node/func.js (100%) rename examples/{app => apps/hellos}/node/func.yaml (100%) rename examples/{app => apps/hellos}/node/package.json (100%) rename examples/{app => apps/hellos}/python/.gitignore (100%) rename examples/{app => apps/hellos}/python/README.md (100%) rename examples/{app => apps/hellos}/python/func.py (100%) rename examples/{app => apps/hellos}/python/func.yaml (100%) rename examples/{app => apps/hellos}/ruby/.gitignore (100%) rename examples/{app => apps/hellos}/ruby/Gemfile (100%) rename examples/{app => apps/hellos}/ruby/README.md (100%) rename examples/{app => apps/hellos}/ruby/func.rb (100%) rename examples/{app => apps/hellos}/ruby/func.yaml (100%) diff --git a/examples/apps/blog/README.md b/examples/apps/blog/README.md new file mode 100644 index 000000000..387090506 --- /dev/null +++ b/examples/apps/blog/README.md @@ -0,0 +1,34 @@ +# Blog API in 10 minutes + +This is a simple blog API with a function to receive a list of posts and a function to create a post. + +## Run it + +``` +# Start MySQL: +docker run --name mysql --net=host -p 3306:3306 -e MYSQL_ROOT_PASSWORD=pass -d mysql:8 +docker run -it --rm --link mysql:mysql mysql mysql -ppass -hmysql -e "create database blog" +docker run -it --rm --link mysql:mysql mysql mysql -ppass -hmysql -e "show databases" + +# create schema +fn run -e DB_USER=root -e DB_PASS=pass schema + +# Test locally: +# Check if any posts, should be none +fn run -e DB_USER=root -e DB_PASS=pass posts +# Add one +cat post.json | fn run -e DB_USER=root -e DB_PASS=pass posts/create +# Check again +fn run -e DB_USER=root -e DB_PASS=pass posts + +# Set app configs +fn apps config set blog DB_USER root +fn apps config set blog DB_PASS pass + +# fn deploy it! +fn deploy --all +``` + +## TODO: + +* [ ] Add some way to ignore funcs on deploy, ie: schema diff --git a/examples/apps/blog/app.yaml b/examples/apps/blog/app.yaml new file mode 100644 index 000000000..f88b61aef --- /dev/null +++ b/examples/apps/blog/app.yaml @@ -0,0 +1 @@ +name: blog diff --git a/examples/apps/blog/func.go b/examples/apps/blog/func.go new file mode 100644 index 000000000..e29f14211 --- /dev/null +++ b/examples/apps/blog/func.go @@ -0,0 +1,22 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" +) + +type Person struct { + Name string +} + +func main() { + p := &Person{Name: "World"} + json.NewDecoder(os.Stdin).Decode(p) + mapD := map[string]string{ + "message": fmt.Sprintf("Hello %s", p.Name), + "posts": "http://localhost:8080/r/blog/posts", + } + mapB, _ := json.Marshal(mapD) + fmt.Println(string(mapB)) +} diff --git a/examples/apps/blog/func.yaml b/examples/apps/blog/func.yaml new file mode 100644 index 000000000..d3c873780 --- /dev/null +++ b/examples/apps/blog/func.yaml @@ -0,0 +1,5 @@ +version: 0.0.20 +runtime: go +entrypoint: ./func +build_image: "" +run_image: "" diff --git a/examples/apps/blog/post.json b/examples/apps/blog/post.json new file mode 100644 index 000000000..7ee51aec5 --- /dev/null +++ b/examples/apps/blog/post.json @@ -0,0 +1,4 @@ +{ + "title": "Blog Post 1", + "body": "This is the body. This is the body. This is the body. This is the body. This is the body. This is the body. " +} \ No newline at end of file diff --git a/examples/apps/blog/posts/Gemfile b/examples/apps/blog/posts/Gemfile new file mode 100644 index 000000000..ea087d0d2 --- /dev/null +++ b/examples/apps/blog/posts/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem 'json', '> 2' +gem 'sequel' +gem 'mysql2' diff --git a/examples/apps/blog/posts/create/Gemfile b/examples/apps/blog/posts/create/Gemfile new file mode 100644 index 000000000..ea087d0d2 --- /dev/null +++ b/examples/apps/blog/posts/create/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem 'json', '> 2' +gem 'sequel' +gem 'mysql2' diff --git a/examples/apps/blog/posts/create/func.rb b/examples/apps/blog/posts/create/func.rb new file mode 100644 index 000000000..9506be7a7 --- /dev/null +++ b/examples/apps/blog/posts/create/func.rb @@ -0,0 +1,20 @@ +require 'json' +require 'sequel' + +DB = Sequel.connect("mysql2://docker.for.mac.localhost/blog?user=#{ENV['DB_USER']}&password=#{ENV['DB_PASS']}") + +payload = STDIN.read +if payload == "" + puts ({"error" => "Invalid input"}).to_json + exit 1 +end + +payload = JSON.parse(payload) + +# create a dataset from the items table +items = DB[:posts] + +# populate the table +items.insert(:title => payload['title'], :body => payload['body']) + +puts ({"status"=>"success", "message" => "Post inserted successfully."}).to_json diff --git a/examples/apps/blog/posts/create/func.yaml b/examples/apps/blog/posts/create/func.yaml new file mode 100644 index 000000000..a6be4ea5c --- /dev/null +++ b/examples/apps/blog/posts/create/func.yaml @@ -0,0 +1,5 @@ +version: 0.0.8 +runtime: ruby +entrypoint: ruby func.rb +build_image: treeder/ruby-mysql +run_image: treeder/ruby-mysql diff --git a/examples/apps/blog/posts/create/test.json b/examples/apps/blog/posts/create/test.json new file mode 100644 index 000000000..391d9b42f --- /dev/null +++ b/examples/apps/blog/posts/create/test.json @@ -0,0 +1,26 @@ +{ + "tests": [ + { + "input": { + "body": { + "name": "Johnny" + } + }, + "output": { + "body": { + "message": "Hello Johnny" + } + } + }, + { + "input": { + "body": "" + }, + "output": { + "body": { + "message": "Hello World" + } + } + } + ] +} diff --git a/examples/apps/blog/posts/func.rb b/examples/apps/blog/posts/func.rb new file mode 100644 index 000000000..0f066615a --- /dev/null +++ b/examples/apps/blog/posts/func.rb @@ -0,0 +1,14 @@ +require 'json' +require 'sequel' + +DB = Sequel.connect("mysql2://docker.for.mac.localhost/blog?user=#{ENV['DB_USER']}&password=#{ENV['DB_PASS']}") + +items = DB[:posts] + +rlist = [] +items.each_with_index do |x,i| + STDERR.puts "item: #{x}" + rlist << x +end +r = {posts: rlist} +puts r.to_json diff --git a/examples/apps/blog/posts/func.yaml b/examples/apps/blog/posts/func.yaml new file mode 100644 index 000000000..f1c8b26ca --- /dev/null +++ b/examples/apps/blog/posts/func.yaml @@ -0,0 +1,5 @@ +version: 0.0.2 +runtime: ruby +entrypoint: ruby func.rb +build_image: treeder/ruby-mysql +run_image: treeder/ruby-mysql diff --git a/examples/apps/blog/posts/test.json b/examples/apps/blog/posts/test.json new file mode 100644 index 000000000..391d9b42f --- /dev/null +++ b/examples/apps/blog/posts/test.json @@ -0,0 +1,26 @@ +{ + "tests": [ + { + "input": { + "body": { + "name": "Johnny" + } + }, + "output": { + "body": { + "message": "Hello Johnny" + } + } + }, + { + "input": { + "body": "" + }, + "output": { + "body": { + "message": "Hello World" + } + } + } + ] +} diff --git a/examples/apps/blog/schema/Gemfile b/examples/apps/blog/schema/Gemfile new file mode 100644 index 000000000..ea087d0d2 --- /dev/null +++ b/examples/apps/blog/schema/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem 'json', '> 2' +gem 'sequel' +gem 'mysql2' diff --git a/examples/apps/blog/schema/create.rb b/examples/apps/blog/schema/create.rb new file mode 100644 index 000000000..4da420d72 --- /dev/null +++ b/examples/apps/blog/schema/create.rb @@ -0,0 +1,10 @@ +require "sequel" + +DB = Sequel.connect("mysql2://docker.for.mac.localhost/blog?user=#{ENV['DB_USER']}&password=#{ENV['DB_PASS']}") + +# create a posts table +DB.create_table :posts do + primary_key :id + String :title + String :body +end diff --git a/examples/apps/blog/schema/func.yaml b/examples/apps/blog/schema/func.yaml new file mode 100644 index 000000000..9931f11e2 --- /dev/null +++ b/examples/apps/blog/schema/func.yaml @@ -0,0 +1,5 @@ +version: 0.0.2 +runtime: ruby +entrypoint: ruby create.rb +build_image: treeder/ruby-mysql +run_image: treeder/ruby-mysql diff --git a/examples/apps/blog/test.json b/examples/apps/blog/test.json new file mode 100644 index 000000000..391d9b42f --- /dev/null +++ b/examples/apps/blog/test.json @@ -0,0 +1,26 @@ +{ + "tests": [ + { + "input": { + "body": { + "name": "Johnny" + } + }, + "output": { + "body": { + "message": "Hello Johnny" + } + } + }, + { + "input": { + "body": "" + }, + "output": { + "body": { + "message": "Hello World" + } + } + } + ] +} diff --git a/examples/app/README.md b/examples/apps/hellos/README.md similarity index 100% rename from examples/app/README.md rename to examples/apps/hellos/README.md diff --git a/examples/app/app.yaml b/examples/apps/hellos/app.yaml similarity index 100% rename from examples/app/app.yaml rename to examples/apps/hellos/app.yaml diff --git a/examples/app/footer/func.rb b/examples/apps/hellos/footer/func.rb similarity index 100% rename from examples/app/footer/func.rb rename to examples/apps/hellos/footer/func.rb diff --git a/examples/app/footer/func.yaml b/examples/apps/hellos/footer/func.yaml similarity index 100% rename from examples/app/footer/func.yaml rename to examples/apps/hellos/footer/func.yaml diff --git a/examples/app/func.go b/examples/apps/hellos/func.go similarity index 100% rename from examples/app/func.go rename to examples/apps/hellos/func.go diff --git a/examples/app/func.yaml b/examples/apps/hellos/func.yaml similarity index 100% rename from examples/app/func.yaml rename to examples/apps/hellos/func.yaml diff --git a/examples/app/header/func.rb b/examples/apps/hellos/header/func.rb similarity index 100% rename from examples/app/header/func.rb rename to examples/apps/hellos/header/func.rb diff --git a/examples/app/header/func.yaml b/examples/apps/hellos/header/func.yaml similarity index 100% rename from examples/app/header/func.yaml rename to examples/apps/hellos/header/func.yaml diff --git a/examples/app/node/.gitignore b/examples/apps/hellos/node/.gitignore similarity index 100% rename from examples/app/node/.gitignore rename to examples/apps/hellos/node/.gitignore diff --git a/examples/app/node/README.md b/examples/apps/hellos/node/README.md similarity index 100% rename from examples/app/node/README.md rename to examples/apps/hellos/node/README.md diff --git a/examples/app/node/func.js b/examples/apps/hellos/node/func.js similarity index 100% rename from examples/app/node/func.js rename to examples/apps/hellos/node/func.js diff --git a/examples/app/node/func.yaml b/examples/apps/hellos/node/func.yaml similarity index 100% rename from examples/app/node/func.yaml rename to examples/apps/hellos/node/func.yaml diff --git a/examples/app/node/package.json b/examples/apps/hellos/node/package.json similarity index 100% rename from examples/app/node/package.json rename to examples/apps/hellos/node/package.json diff --git a/examples/app/python/.gitignore b/examples/apps/hellos/python/.gitignore similarity index 100% rename from examples/app/python/.gitignore rename to examples/apps/hellos/python/.gitignore diff --git a/examples/app/python/README.md b/examples/apps/hellos/python/README.md similarity index 100% rename from examples/app/python/README.md rename to examples/apps/hellos/python/README.md diff --git a/examples/app/python/func.py b/examples/apps/hellos/python/func.py similarity index 100% rename from examples/app/python/func.py rename to examples/apps/hellos/python/func.py diff --git a/examples/app/python/func.yaml b/examples/apps/hellos/python/func.yaml similarity index 100% rename from examples/app/python/func.yaml rename to examples/apps/hellos/python/func.yaml diff --git a/examples/app/ruby/.gitignore b/examples/apps/hellos/ruby/.gitignore similarity index 100% rename from examples/app/ruby/.gitignore rename to examples/apps/hellos/ruby/.gitignore diff --git a/examples/app/ruby/Gemfile b/examples/apps/hellos/ruby/Gemfile similarity index 100% rename from examples/app/ruby/Gemfile rename to examples/apps/hellos/ruby/Gemfile diff --git a/examples/app/ruby/README.md b/examples/apps/hellos/ruby/README.md similarity index 100% rename from examples/app/ruby/README.md rename to examples/apps/hellos/ruby/README.md diff --git a/examples/app/ruby/func.rb b/examples/apps/hellos/ruby/func.rb similarity index 100% rename from examples/app/ruby/func.rb rename to examples/apps/hellos/ruby/func.rb diff --git a/examples/app/ruby/func.yaml b/examples/apps/hellos/ruby/func.yaml similarity index 100% rename from examples/app/ruby/func.yaml rename to examples/apps/hellos/ruby/func.yaml