diff --git a/DotNetSampleApp/Controllers/Customers.cs b/DotNetSampleApp/Controllers/Customers.cs
index fc5480d..122896d 100644
--- a/DotNetSampleApp/Controllers/Customers.cs
+++ b/DotNetSampleApp/Controllers/Customers.cs
@@ -6,7 +6,7 @@
namespace DotNetSampleApp.Controllers;
///
-/// Customers controller
+/// Customers controller
///
/// Fauna Client
[ApiController,
@@ -30,10 +30,10 @@ public async Task GetCustomer([FromRoute] string customerId)
//
// Use projection to only return the fields you need.
var query = Query.FQL($"""
- let customer: Any = Customer.byId({customerId})!
+ let customer = Customer.byId({customerId})!
{QuerySnippets.CustomerResponse()}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var res = await client.QueryAsync(query);
@@ -52,16 +52,16 @@ public async Task CreateCustomer(CustomerRequest customer)
{
// Create a new Customer document with the provided fields.
var query = Query.FQL($"""
- let customer: Any = Customer.create({customer})
+ let customer = Customer.create({customer})
{QuerySnippets.CustomerResponse()}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var res = await client.QueryAsync(query);
return CreatedAtAction(nameof(GetCustomer), new { customerId = res.Data.Id }, res.Data);
}
-
+
///
/// Update Customer Details
///
@@ -85,10 +85,10 @@ public async Task UpdateCustomer(
//
// Use projection to only return the fields you need.
var query = Query.FQL($"""
- let customer: Any = Customer.byId({customerId})!.update({customer})
+ let customer = Customer.byId({customerId})!.update({customer})
{QuerySnippets.CustomerResponse()}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var res = await client.QueryAsync(query);
@@ -116,25 +116,23 @@ public async Task GetOrdersByCustomer(
// Make sure to URL encode the `afterToken` value to preserve these
// characters in URLs.
var query = !string.IsNullOrEmpty(afterToken)
-
+
// Paginate with the after token if it's present.
? Query.FQL($"Set.paginate({afterToken})")
-
+
// Define an FQL query to retrieve a page of orders for a given customer.
// Get the Customer document by id, using the ! operator to assert that the document exists.
// If the document does not exist, Fauna will throw a document_not_found error. We then
// use the Order.byCustomer index to retrieve all orders for that customer and map over
// the results to return only the fields we care about.
: Query.FQL($$"""
- let customer: Any = Customer.byId({{customerId}})!
+ let customer = Customer.byId({{customerId}})!
Order.byCustomer(customer).pageSize({{pageSize}}).map((order) => {
- let order: Any = order
-
// Return the order.
{{QuerySnippets.OrderResponse()}}
})
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var result = await client.QueryAsync>(query);
@@ -156,12 +154,12 @@ public async Task CreateCart([FromRoute] string customerId)
// Call our getOrCreateCart UDF to get the customer's cart. The function
// definition can be found 'server/schema/functions.fsl'.
var query = Query.FQL($"""
- let order: Any = getOrCreateCart({customerId})
-
+ let order = getOrCreateCart({customerId})
+
// Return the cart.
{QuerySnippets.OrderResponse()}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var res = await client.QueryAsync(query);
@@ -184,12 +182,12 @@ public async Task AddItemToCart([FromRoute] string customerId, Ad
// definition can be found 'server/schema/functions.fsl'.
var query = Query.FQL($"""
let req = {item}
- let order: Any = createOrUpdateCartItem({customerId}, req.productName, req.quantity)
+ let order = createOrUpdateCartItem({customerId}, req.productName, req.quantity)
// Return the cart as an OrderResponse object.
{QuerySnippets.OrderResponse()}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var res = await client.QueryAsync(query);
@@ -210,12 +208,12 @@ public async Task GetCart([FromRoute] string customerId)
// Get the customer's cart by id, using the ! operator to assert that the document exists.
// If the document does not exist, Fauna will throw a document_not_found error.
var query = Query.FQL($"""
- let order: Any = Customer.byId({customerId})!.cart
-
+ let order = Customer.byId({customerId})!.cart
+
// Return the cart as an OrderResponse object.
{QuerySnippets.OrderResponse()}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var res = await client.QueryAsync(query);
diff --git a/DotNetSampleApp/Controllers/Orders.cs b/DotNetSampleApp/Controllers/Orders.cs
index 9148fa4..ab28892 100644
--- a/DotNetSampleApp/Controllers/Orders.cs
+++ b/DotNetSampleApp/Controllers/Orders.cs
@@ -26,10 +26,10 @@ public class Orders(Client client) : ControllerBase
public async Task GetOrder([FromRoute] string id)
{
var query = Query.FQL($"""
- let order: Any = Order.byId({id})!
+ let order = Order.byId({id})!
{QuerySnippets.OrderResponse()}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var res = await client.QueryAsync(query);
@@ -58,19 +58,19 @@ OrderRequest order
// for validating that the order in a valid state to be processed and decrements the stock
// of each product in the order. This ensures that the product stock is updated in the same transaction
// as the order status.
- var query = order.Status == "processing"
+ var query = order.Status == "processing"
? Query.FQL($"""
let req = {order}
- let order: Any = checkout({id}, req.status, req.payment)
+ let order = checkout({id}, req.status, req.payment)
{QuerySnippets.OrderResponse()}
""")
-
+
// Define an FQL query to update the order. The query first retrieves the order by id
// using the Order.byId function. If the order does not exist, Fauna will throw a document_not_found
// error. We then use the validateOrderStatusTransition UDF to ensure that the order status transition
// is valid. If the transition is not valid, the UDF will throw an abort error.
: Query.FQL($$"""
- let order: Any = Order.byId({{id}})!
+ let order = Order.byId({{id}})!
let req = {{order}}
// Validate the order status transition if a status is provided.
diff --git a/DotNetSampleApp/Controllers/Products.cs b/DotNetSampleApp/Controllers/Products.cs
index ae0e74e..f663aad 100644
--- a/DotNetSampleApp/Controllers/Products.cs
+++ b/DotNetSampleApp/Controllers/Products.cs
@@ -36,24 +36,24 @@ public async Task PaginateProducts(
// fragment will either return all products sorted by category or all products in a specific
// category depending on whether the category query parameter is provided. This will later
// be embedded in a larger query.
- var queryPrefix = string.IsNullOrEmpty(category)
- ? Query.FQL($"Product.sortedByCategory().pageSize({pageSize})")
+ var queryPrefix = string.IsNullOrEmpty(category)
+ ? Query.FQL($"Product.sortedByCategory().pageSize({pageSize})")
: Query.FQL($"""
let category = Category.byName({category}).first()
if (category == null) abort("Category does not exist.")
-
+
Product.byCategory(category).pageSize({pageSize})
""");
-
+
// The `afterToken` parameter contains a Fauna `after` cursor.
// `after` cursors may contain special characters, such as `.` or `+`).
// Make sure to URL encode the `afterToken` value to preserve these
// characters in URLs.
- var query = !string.IsNullOrEmpty(afterToken)
-
+ var query = !string.IsNullOrEmpty(afterToken)
+
// Paginate with the after token if it's present.
? Query.FQL($"Set.paginate({afterToken})")
-
+
// Define the main query. This query will return a page of products using the query fragment
// defined above.
: Query.FQL($$"""
@@ -90,17 +90,17 @@ public async Task CreateProduct(ProductRequest product)
if (category == null) abort("Category does not exist.")
// Create the product with the given values.
- let args = {
+ let args = {
name: {{product.Name}},
price: {{product.Price}},
stock: {{product.Stock}},
description: {{product.Description}},
- category: category
+ category: category
}
- let product: Any = Product.create(args)
+ let product = Product.create(args)
{{QuerySnippets.ProductResponse()}}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var result = await client.QueryAsync(query);
@@ -125,7 +125,7 @@ public async Task UpdateProductById(
var query = Query.FQL($$"""
// Get the product by id, using the ! operator to assert that the product exists.
// If it does not exist Fauna will throw a document_not_found error.
- let product: Any = Product.byId({{id}})!
+ let product = Product.byId({{id}})!
if (product == null) abort("Product does not exist.")
// Get the category by name. We can use .first() here because we know that the category
@@ -134,7 +134,7 @@ public async Task UpdateProductById(
if (category == null) abort("Category does not exist.")
// Update category if a new one was provided
- let newCategory: Any = Category.byName({{product.Category}})?.first()
+ let newCategory = Category.byName({{product.Category}})?.first()
let fields = {
name: {{product.Name}},
@@ -154,7 +154,7 @@ public async Task UpdateProductById(
{{QuerySnippets.ProductResponse()}}
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var result = await client.QueryAsync(query);
@@ -185,10 +185,10 @@ public async Task SearchProducts(
// Make sure to URL encode the `afterToken` value to preserve these
// characters in URLs.
var query = !string.IsNullOrEmpty(afterToken)
-
+
// Paginate with the after token if it's present.
? Query.FQL($"Set.paginate({afterToken})")
-
+
// This is an example of a covered query. A covered query is a query where all fields
// returned are indexed fields. In this case, we are querying the Product collection
// for products with a price between minPrice and maxPrice. We are also limiting the
@@ -204,7 +204,7 @@ public async Task SearchProducts(
{{QuerySnippets.ProductResponse()}}
})
""");
-
+
// Connect to fauna using the client. The query method accepts an FQL query
// as a parameter and a generic type parameter representing the return type.
var result = await client.QueryAsync>(query);
diff --git a/DotNetSampleApp/Controllers/QuerySnippets.cs b/DotNetSampleApp/Controllers/QuerySnippets.cs
index ffd9b84..18ad1c2 100644
--- a/DotNetSampleApp/Controllers/QuerySnippets.cs
+++ b/DotNetSampleApp/Controllers/QuerySnippets.cs
@@ -8,7 +8,7 @@ namespace DotNetSampleApp.Controllers;
public static class QuerySnippets
{
///
- /// A Query snippet for customer response projection.
+ /// A Query snippet for customer response projection.
///
///
public static Query CustomerResponse()
@@ -25,11 +25,11 @@ public static Query CustomerResponse()
}
///
- /// A Query snippet for order response projection.
+ /// A Query snippet for order response projection.
///
///
public static Query OrderResponse()
- {
+ {
return Query.FQL($$"""
{
id: order.id,
@@ -63,7 +63,7 @@ public static Query OrderResponse()
}
///
- /// A Query snippet for product response projection.
+ /// A Query snippet for product response projection.
///
///
public static Query ProductResponse()
@@ -71,7 +71,6 @@ public static Query ProductResponse()
return Query.FQL($$"""
// Use projection to return only the necessary fields.
let product: Any = product
- let category: Any = product.category
product {
id: product.id,
name: product.name,
@@ -79,11 +78,11 @@ public static Query ProductResponse()
description: product.description,
stock: product.stock,
category: {
- id: category.id,
- name: category.name,
- description: category.description
+ id: product.category.id,
+ name: product.category.name,
+ description: product.category.description
},
}
""");
}
-}
\ No newline at end of file
+}
diff --git a/DotNetSampleApp/Services/SeedService.cs b/DotNetSampleApp/Services/SeedService.cs
index eb55cda..44fffbb 100644
--- a/DotNetSampleApp/Services/SeedService.cs
+++ b/DotNetSampleApp/Services/SeedService.cs
@@ -45,7 +45,7 @@ public static void Init(Client client)
{name: 'The Godfather II', price: 1299, description: 'A movie by Francis Ford Coppola', stock: 10, category: 'movies'},
{name: 'The Godfather III', price: 1299, description: 'A movie by Francis Ford Coppola', stock: 10, category: 'movies'}
].map(p => {
- let existing: Any = Product.byName(p.name).first()
+ let existing = Product.byName(p.name).first()
if (existing != null) {
existing!.update({ stock: p.stock })
} else {
@@ -85,16 +85,16 @@ public static void Init(Client client)
client.QueryAsync(Query.FQL($$"""
let customer = Customer.byEmail('fake@fauna.com').first()!
let orders = ['cart', 'processing', 'shipped', 'delivered'].map(status => {
- let order: Any = Order.byCustomer(customer).firstWhere(o => o.status == status)
+ let order = Order.byCustomer(customer).firstWhere(o => o.status == status)
if (order == null) {
- let newOrder: Any = Order.create({
+ let newOrder = Order.create({
customer: customer,
status: status,
createdAt: Time.now(),
payment: {}
})
- let product: Any = Product.byName('Drone').first()!
- let orderItem: Any = OrderItem.create({ order: newOrder, product: product, quantity: 1 })
+ let product = Product.byName('Drone').first()!
+ let orderItem = OrderItem.create({ order: newOrder, product: product, quantity: 1 })
orderItem
newOrder
} else {
diff --git a/README.md b/README.md
index e5e1d5c..98ae338 100644
--- a/README.md
+++ b/README.md
@@ -265,7 +265,6 @@ Customer documents and related API responses:
+ // Use a computed field to calculate the customer's cumulative purchase total.
+ // The field sums purchase `total` values from the customer's linked Order documents.
+ compute totalPurchaseAmt: Number = (customer => customer.orders.fold(0, (sum, order) => {
- + let order: Any = order
+ sum + order.total
+ }))
...
diff --git a/schema/collections.fsl b/schema/collections.fsl
index e64c5ca..a0de39c 100644
--- a/schema/collections.fsl
+++ b/schema/collections.fsl
@@ -72,9 +72,8 @@ collection Order {
compute items: Set = (order => OrderItem.byOrder(order))
compute total: Number = (order => order.items.fold(0, (sum, orderItem) => {
- let orderItem: Any = orderItem
if (orderItem.product != null) {
- sum + orderItem.product.price * orderItem.quantity
+ sum + orderItem.product!.price * orderItem.quantity
} else {
sum
}
diff --git a/schema/functions.fsl b/schema/functions.fsl
index 19896e1..d34cc59 100644
--- a/schema/functions.fsl
+++ b/schema/functions.fsl
@@ -70,7 +70,7 @@ function getOrCreateCart(id) {
function checkout(orderId, status, payment) {
// Find the order by id, using the ! operator to assert that the order exists.
- let order: Any = Order.byId(orderId)!
+ let order = Order.byId(orderId)!
// Check that we are setting the order to the processing status. If not, we should
// not be calling this function.
@@ -98,7 +98,7 @@ function checkout(orderId, status, payment) {
// Check that the order items are still in stock.
order!.items.forEach((item) => {
- let product: Any = item.product
+ let product = item.product
if (product.stock < item.quantity) {
abort("One of the selected products does not have the requested quantity in stock.")
}
@@ -106,7 +106,7 @@ function checkout(orderId, status, payment) {
// Decrement the stock of each product in the order.
order!.items.forEach((item) => {
- let product: Any = item.product
+ let product = item.product
product.update({ stock: product.stock - item.quantity })
})