Skip to content

Commit 78cb9a8

Browse files
authored
JavaScript samples (#234)
* initial checkin * add some more samples * input binding tests * add outputbinding samples and tests * remove host.json * fix tests * fix casing issue in the json keys * clean up * add samples-js to output folder for tests * undo fix #232 * add func extensions sync while testing * merge casing fix * undo local change * remove sql proj reference. * refactor logic * add outputbinding with get * empty query string issue * remove extension.csproj, use from extension bundle * add bundle to host.json * remove tests and cleanup samples * remove duplicate upsertProducts * remove get from output bindings * remove commadTyoe * remove negative tests * ready from params * update get when reading from params * remove reading from body * comments and cleanup1 * use query instead of params * missed renames
1 parent f9372a4 commit 78cb9a8

File tree

32 files changed

+671
-55
lines changed

32 files changed

+671
-55
lines changed

samples/samples-csharp/GlobalSuppressions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.InputBindingSamples.GetProductsNameEmpty.Run(Microsoft.AspNetCore.Http.HttpRequest,System.Collections.Generic.IEnumerable{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})~Microsoft.AspNetCore.Mvc.IActionResult")]
1616
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.InputBindingSamples.GetProductsNameNull.Run(Microsoft.AspNetCore.Http.HttpRequest,System.Collections.Generic.IEnumerable{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})~Microsoft.AspNetCore.Mvc.IActionResult")]
1717
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.InputBindingSamples.GetProductsStoredProcedure.Run(Microsoft.AspNetCore.Http.HttpRequest,System.Collections.Generic.IEnumerable{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})~Microsoft.AspNetCore.Mvc.IActionResult")]
18-
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples.AddProductsArray.Run(Microsoft.AspNetCore.Http.HttpRequest,Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product[]@)~Microsoft.AspNetCore.Mvc.IActionResult")]
1918
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples.AddProductsAsyncCollector.Run(Microsoft.AspNetCore.Http.HttpRequest,Microsoft.Azure.WebJobs.IAsyncCollector{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})~System.Threading.Tasks.Task{Microsoft.AspNetCore.Mvc.IActionResult}")]
2019
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples.AddProductsCollector.Run(Microsoft.AspNetCore.Http.HttpRequest,Microsoft.Azure.WebJobs.ICollector{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})~Microsoft.AspNetCore.Mvc.IActionResult")]
2120
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples.TimerTriggerProducts.Run(Microsoft.Azure.WebJobs.TimerInfo,Microsoft.Extensions.Logging.ILogger,Microsoft.Azure.WebJobs.ICollector{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})")]

samples/samples-csharp/OutputBindingSamples/AddProduct.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

4-
using Microsoft.AspNetCore.Http;
54
using Microsoft.AspNetCore.Mvc;
65
using Microsoft.Azure.WebJobs.Extensions.Http;
76
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common;
8-
97
namespace Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples
108
{
119
public static class AddProduct
1210
{
1311
[FunctionName("AddProduct")]
1412
public static IActionResult Run(
15-
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "addproduct")]
16-
HttpRequest req,
13+
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "addproduct")]
14+
[FromBody] Product prod,
1715
[Sql("dbo.Products", ConnectionStringSetting = "SqlConnectionString")] out Product product)
1816
{
19-
product = new Product
20-
{
21-
Name = req.Query["name"],
22-
ProductID = int.Parse(req.Query["id"]),
23-
Cost = int.Parse(req.Query["cost"])
24-
};
17+
product = prod;
2518
return new CreatedResult($"/api/addproduct", product);
2619
}
2720
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using Microsoft.AspNetCore.Http;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Microsoft.Azure.WebJobs.Extensions.Http;
7+
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common;
8+
9+
namespace Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples
10+
{
11+
public static class AddProductParams
12+
{
13+
[FunctionName("AddProductParams")]
14+
public static IActionResult Run(
15+
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "addproduct-params")]
16+
HttpRequest req,
17+
[Sql("dbo.Products", ConnectionStringSetting = "SqlConnectionString")] out Product product)
18+
{
19+
product = new Product
20+
{
21+
Name = req.Query["name"],
22+
ProductID = int.Parse(req.Query["productId"]),
23+
Cost = int.Parse(req.Query["cost"])
24+
};
25+
return new CreatedResult($"/api/addproduct", product);
26+
}
27+
}
28+
}

samples/samples-csharp/OutputBindingSamples/AddProductsArray.cs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,24 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

4-
using Microsoft.AspNetCore.Http;
54
using Microsoft.AspNetCore.Mvc;
65
using Microsoft.Azure.WebJobs.Extensions.Http;
76
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common;
7+
using System.Collections.Generic;
88

99
namespace Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples
1010
{
1111
public static class AddProductsArray
1212
{
1313
[FunctionName("AddProductsArray")]
1414
public static IActionResult Run(
15-
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "addproducts-array")]
16-
HttpRequest req,
15+
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "addproducts-array")]
16+
[FromBody] List<Product> products,
1717
[Sql("dbo.Products", ConnectionStringSetting = "SqlConnectionString")] out Product[] output)
1818
{
19-
// Suppose that the ProductID column is the primary key in the Products table, and the
20-
// table already contains a row with ProductID = 1. In that case, the row will be updated
21-
// instead of inserted to have values Name = "Cup" and Cost = 2.
22-
output = new[]
23-
{
24-
new Product
25-
{
26-
ProductID = 1,
27-
Name = "Cup",
28-
Cost = 2
29-
},
30-
new Product
31-
{
32-
ProductID = 2,
33-
Name = "Glasses",
34-
Cost = 12
35-
}
36-
};
19+
// Upsert the products, which will insert them into the Products table if the primary key (ProductId) for that item doesn't exist.
20+
// If it does then update it to have the new name and cost
21+
output = products.ToArray();
3722
return new CreatedResult($"/api/addproducts-array", output);
3823
}
3924
}

samples/samples-js/.funcignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
*.js.map
2+
*.ts
3+
.git*
4+
.vscode
5+
local.settings.json
6+
test
7+
tsconfig.json

samples/samples-js/.gitignore

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
9+
# Diagnostic reports (https://nodejs.org/api/report.html)
10+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Directory for instrumented libs generated by jscoverage/JSCover
19+
lib-cov
20+
21+
# Coverage directory used by tools like istanbul
22+
coverage
23+
24+
# nyc test coverage
25+
.nyc_output
26+
27+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
28+
.grunt
29+
30+
# Bower dependency directory (https://bower.io/)
31+
bower_components
32+
33+
# node-waf configuration
34+
.lock-wscript
35+
36+
# Compiled binary addons (https://nodejs.org/api/addons.html)
37+
build/Release
38+
39+
# Dependency directories
40+
node_modules/
41+
jspm_packages/
42+
43+
# TypeScript v1 declaration files
44+
typings/
45+
46+
# Optional npm cache directory
47+
.npm
48+
49+
# Optional eslint cache
50+
.eslintcache
51+
52+
# Optional REPL history
53+
.node_repl_history
54+
55+
# Output of 'npm pack'
56+
*.tgz
57+
58+
# Yarn Integrity file
59+
.yarn-integrity
60+
61+
# dotenv environment variables file
62+
.env
63+
.env.test
64+
65+
# parcel-bundler cache (https://parceljs.org/)
66+
.cache
67+
68+
# next.js build output
69+
.next
70+
71+
# nuxt.js build output
72+
.nuxt
73+
74+
# vuepress build output
75+
.vuepress/dist
76+
77+
# Serverless directories
78+
.serverless/
79+
80+
# FuseBox cache
81+
.fusebox/
82+
83+
# DynamoDB Local files
84+
.dynamodb/
85+
86+
# TypeScript output
87+
dist
88+
out
89+
90+
# Azure Functions artifacts
91+
bin
92+
obj
93+
appsettings.json
94+
local.settings.json
95+
96+
# Azurite artifacts
97+
__blobstorage__
98+
__queuestorage__
99+
__azurite_db*__.json
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"bindings": [
3+
{
4+
"authLevel": "function",
5+
"name": "req",
6+
"direction": "in",
7+
"type": "httpTrigger",
8+
"methods": [
9+
"post"
10+
],
11+
"route": "addproduct"
12+
},
13+
{
14+
"name": "$return",
15+
"type": "http",
16+
"direction": "out"
17+
},
18+
{
19+
"name": "product",
20+
"type": "sql",
21+
"direction": "out",
22+
"commandText": "[dbo].[Products]",
23+
"connectionStringSetting": "SqlConnectionString"
24+
}
25+
],
26+
"disabled": false
27+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Upsert the product, which will insert it into the Products table if the primary key (ProductId) for that item doesn't exist.
2+
// If it does then update it to have the new name and cost.
3+
module.exports = async function (context, req) {
4+
// Note that this expects the body to be a JSON object or array of objects which have a property
5+
// matching each of the columns in the table to upsert to.
6+
context.bindings.product = req.body;
7+
8+
return {
9+
status: 201,
10+
body: req.body
11+
};
12+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"bindings": [
3+
{
4+
"authLevel": "function",
5+
"name": "req",
6+
"direction": "in",
7+
"type": "httpTrigger",
8+
"methods": [
9+
"get"
10+
],
11+
"route": "addproduct-params"
12+
},
13+
{
14+
"name": "$return",
15+
"type": "http",
16+
"direction": "out"
17+
},
18+
{
19+
"name": "product",
20+
"type": "sql",
21+
"direction": "out",
22+
"commandText": "[dbo].[Products]",
23+
"connectionStringSetting": "SqlConnectionString"
24+
}
25+
],
26+
"disabled": false
27+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = async function (context, req) {
2+
context.log('JavaScript HTTP trigger function processed a request.');
3+
4+
const newProduct = {
5+
"productId": req.query?.productId,
6+
"name": req.query?.name,
7+
"cost": req.query?.cost
8+
};
9+
10+
context.bindings.product = JSON.stringify(newProduct);
11+
12+
return {
13+
status: 201,
14+
body: context.bindings.product
15+
};
16+
}

0 commit comments

Comments
 (0)