1- using dotnet_sample_app . Models ;
2- using dotnet_sample_app . Repositories ;
1+ using DotNetSampleApp . Models ;
32using Fauna ;
43using Fauna . Types ;
54using Microsoft . AspNetCore . Mvc ;
65
7- namespace dotnet_sample_app . Controllers ;
6+ namespace DotNetSampleApp . Controllers ;
87
98/// <summary>
109/// Customers controller
@@ -14,21 +13,6 @@ namespace dotnet_sample_app.Controllers;
1413 Route ( "/[controller]" ) ]
1514public class Customers ( Client client ) : ControllerBase
1615{
17- private readonly CustomerDb _customerDb = client . DataContext < CustomerDb > ( ) ;
18-
19- /// <summary>
20- /// Creates a new Customer
21- /// </summary>
22- /// <returns>Customer Details</returns>
23- [ ProducesResponseType ( typeof ( Customer ) , StatusCodes . Status201Created ) ]
24- [ ProducesResponseType ( StatusCodes . Status400BadRequest ) ]
25- [ ProducesResponseType ( StatusCodes . Status500InternalServerError ) ]
26- [ HttpPost ]
27- public async Task < IActionResult > CreateCustomer ( CustomerRequest customer )
28- {
29- return StatusCode ( StatusCodes . Status201Created , await _customerDb . Create ( customer ) ) ;
30- }
31-
3216
3317 /// <summary>
3418 /// Get Customer by ID
@@ -41,9 +25,43 @@ public async Task<IActionResult> CreateCustomer(CustomerRequest customer)
4125 [ HttpGet ( "{customerId}" ) ]
4226 public async Task < IActionResult > GetCustomer ( [ FromRoute ] string customerId )
4327 {
44- return Ok ( await _customerDb . Get ( customerId ) ) ;
28+ // Get the Customer document by `id`, using the ! operator to assert that the document exists.
29+ // If the document does not exist, Fauna will throw a document_not_found error.
30+ //
31+ // Use projection to only return the fields you need.
32+ var query = Query . FQL ( $ """
33+ let customer: Any = Customer.byId({ customerId } )!
34+ { QuerySnippets . CustomerResponse ( ) }
35+ """ ) ;
36+
37+ // Connect to fauna using the client. The query method accepts an FQL query
38+ // as a parameter and a generic type parameter representing the return type.
39+ var res = await client . QueryAsync < Customer > ( query ) ;
40+ return Ok ( res . Data ) ;
4541 }
4642
43+ /// <summary>
44+ /// Creates a new Customer
45+ /// </summary>
46+ /// <returns>Customer Details</returns>
47+ [ ProducesResponseType ( typeof ( Customer ) , StatusCodes . Status201Created ) ]
48+ [ ProducesResponseType ( StatusCodes . Status400BadRequest ) ]
49+ [ ProducesResponseType ( StatusCodes . Status500InternalServerError ) ]
50+ [ HttpPost ]
51+ public async Task < IActionResult > CreateCustomer ( CustomerRequest customer )
52+ {
53+ // Create a new Customer document with the provided fields.
54+ var query = Query . FQL ( $ """
55+ let customer: Any = Customer.create({ customer } )
56+ { QuerySnippets . CustomerResponse ( ) }
57+ """ ) ;
58+
59+ // Connect to fauna using the client. The query method accepts an FQL query
60+ // as a parameter and a generic type parameter representing the return type.
61+ var res = await client . QueryAsync < Customer > ( query ) ;
62+ return StatusCode ( StatusCodes . Status201Created , res . Data ) ;
63+ }
64+
4765 /// <summary>
4866 /// Update Customer Details
4967 /// </summary>
@@ -52,26 +70,75 @@ public async Task<IActionResult> GetCustomer([FromRoute] string customerId)
5270 [ ProducesResponseType ( StatusCodes . Status400BadRequest ) ]
5371 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
5472 [ ProducesResponseType ( StatusCodes . Status500InternalServerError ) ]
55- [ HttpPatch ( "{customerId}" ) ]
73+ [ HttpPost ( "{customerId}" ) ]
5674 public async Task < IActionResult > UpdateCustomer (
5775 [ FromRoute ] string customerId ,
5876 CustomerRequest customer )
5977 {
60- return Ok ( await _customerDb . Update ( customerId , customer ) ) ;
78+ // Get the Customer document by `customerId`, using the ! operator to assert that the document exists.
79+ // If the document does not exist, Fauna will throw a document_not_found error.
80+ //
81+ // All unannotated fields and fields annotated with @FaunaField will be serialized, including
82+ // those with `null` values. When an update is made to a field with a null value, that value of
83+ // that field is unset on the document. Partial updates must be made with a dedicated class,
84+ // anonymous class, or Map.
85+ //
86+ // Use projection to only return the fields you need.
87+ var query = Query . FQL ( $ """
88+ let customer: Any = Customer.byId({ customerId } )!.update({ customer } )
89+ { QuerySnippets . CustomerResponse ( ) }
90+ """ ) ;
91+
92+ // Connect to fauna using the client. The query method accepts an FQL query
93+ // as a parameter and a generic type parameter representing the return type.
94+ var res = await client . QueryAsync < Customer > ( query ) ;
95+ return StatusCode ( StatusCodes . Status201Created , res . Data ) ;
6196 }
6297
6398 /// <summary>
6499 /// Return all orders for a specific customer.
65100 /// </summary>
66101 /// <param name="customerId">Customer ID</param>
102+ /// <param name="afterToken">The after token for pagination.</param>
103+ /// <param name="pageSize">A page size. Ignored if after token is provided.</param>
67104 /// <returns>List of Orders.</returns>
68105 [ ProducesResponseType ( typeof ( Page < Order > ) , StatusCodes . Status200OK ) ]
69106 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
70107 [ ProducesResponseType ( StatusCodes . Status500InternalServerError ) ]
71108 [ HttpGet ( "{customerId}/orders" ) ]
72- public async Task < IActionResult > GetOrdersByCustomer ( [ FromRoute ] string customerId )
109+ public async Task < IActionResult > GetOrdersByCustomer (
110+ [ FromRoute ] string customerId ,
111+ [ FromQuery ] string ? afterToken ,
112+ [ FromQuery ] int pageSize = 10 )
73113 {
74- return Ok ( await _customerDb . GetOrdersByCustomer ( customerId ) ) ;
114+ // The `afterToken` parameter contains a Fauna `after` cursor.
115+ // `after` cursors may contain special characters, such as `.` or `+`).
116+ // Make sure to URL encode the `afterToken` value to preserve these
117+ // characters in URLs.
118+ var query = ! string . IsNullOrEmpty ( afterToken )
119+
120+ // Paginate with the after token if it's present.
121+ ? Query . FQL ( $ "Set.paginate({ afterToken } )")
122+
123+ // Define an FQL query to retrieve a page of orders for a given customer.
124+ // Get the Customer document by id, using the ! operator to assert that the document exists.
125+ // If the document does not exist, Fauna will throw a document_not_found error. We then
126+ // use the Order.byCustomer index to retrieve all orders for that customer and map over
127+ // the results to return only the fields we care about.
128+ : Query . FQL ( @$ """
129+ let customer: Any = Customer.byId({ customerId } )!
130+ Order.byCustomer(customer).pageSize({ pageSize } ).map((order) => {{
131+ let order: Any = order
132+
133+ // Return the order.
134+ { QuerySnippets . OrderResponse ( ) }
135+ }})
136+ """ ) ;
137+
138+ // Connect to fauna using the client. The query method accepts an FQL query
139+ // as a parameter and a generic type parameter representing the return type.
140+ var result = await client . QueryAsync < Page < Order > > ( query ) ;
141+ return Ok ( result . Data ) ;
75142 }
76143
77144
@@ -86,7 +153,19 @@ public async Task<IActionResult> GetOrdersByCustomer([FromRoute] string customer
86153 [ HttpPost ( "{customerId}/cart" ) ]
87154 public async Task < IActionResult > CreateCart ( [ FromRoute ] string customerId )
88155 {
89- return Ok ( await _customerDb . GetOrCreateCart ( customerId ) ) ;
156+ // Call our getOrCreateCart UDF to get the customer's cart. The function
157+ // definition can be found 'server/schema/functions.fsl'.
158+ var query = Query . FQL ( $ """
159+ let order: Any = getOrCreateCart({ customerId } )
160+
161+ // Return the cart.
162+ { QuerySnippets . OrderResponse ( ) }
163+ """ ) ;
164+
165+ // Connect to fauna using the client. The query method accepts an FQL query
166+ // as a parameter and a generic type parameter representing the return type.
167+ var res = await client . QueryAsync < Order > ( query ) ;
168+ return StatusCode ( StatusCodes . Status201Created , res . Data ) ;
90169 }
91170
92171 /// <summary>
@@ -101,7 +180,20 @@ public async Task<IActionResult> CreateCart([FromRoute] string customerId)
101180 [ HttpPost ( "{customerId}/cart/item" ) ]
102181 public async Task < IActionResult > AddItemToCart ( [ FromRoute ] string customerId , AddItemToCartRequest item )
103182 {
104- return Ok ( await _customerDb . AddItemToCart ( customerId , item ) ) ;
183+ // Call our createOrUpdateCartItem UDF to add an item to the customer's cart. The function
184+ // definition can be found 'server/schema/functions.fsl'.
185+ var query = Query . FQL ( $ """
186+ let req = { item }
187+ let order: Any = createOrUpdateCartItem({ customerId } , req.productName, req.quantity)
188+
189+ // Return the cart as an OrderResponse object.
190+ { QuerySnippets . OrderResponse ( ) }
191+ """ ) ;
192+
193+ // Connect to fauna using the client. The query method accepts an FQL query
194+ // as a parameter and a generic type parameter representing the return type.
195+ var res = await client . QueryAsync < Order > ( query ) ;
196+ return StatusCode ( StatusCodes . Status201Created , res . Data ) ;
105197 }
106198
107199 /// <summary>
@@ -115,22 +207,18 @@ public async Task<IActionResult> AddItemToCart([FromRoute] string customerId, Ad
115207 [ HttpGet ( "{customerId}/cart" ) ]
116208 public async Task < IActionResult > GetCart ( [ FromRoute ] string customerId )
117209 {
118- return Ok ( await _customerDb . GetOrCreateCart ( customerId ) ) ;
119- }
120-
121- /// <summary>
122- /// Delete Customer
123- /// </summary>
124- /// <param name="customerId">Customer ID</param>
125- /// <returns>No Content</returns>
126- [ ProducesResponseType ( typeof ( Cart ) , StatusCodes . Status200OK ) ]
127- [ ProducesResponseType ( StatusCodes . Status400BadRequest ) ]
128- [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
129- [ ProducesResponseType ( StatusCodes . Status500InternalServerError ) ]
130- [ HttpDelete ( "{customerId}" ) ]
131- public async Task < IActionResult > DeleteCustomer ( [ FromRoute ] string customerId )
132- {
133- await _customerDb . Delete ( customerId ) ;
134- return NoContent ( ) ;
210+ // Get the customer's cart by id, using the ! operator to assert that the document exists.
211+ // If the document does not exist, Fauna will throw a document_not_found error.
212+ var query = Query . FQL ( $ """
213+ let order: Any = Customer.byId({ customerId } )!.cart
214+
215+ // Return the cart as an OrderResponse object.
216+ { QuerySnippets . OrderResponse ( ) }
217+ """ ) ;
218+
219+ // Connect to fauna using the client. The query method accepts an FQL query
220+ // as a parameter and a generic type parameter representing the return type.
221+ var res = await client . QueryAsync < Order > ( query ) ;
222+ return StatusCode ( StatusCodes . Status201Created , res . Data ) ;
135223 }
136- }
224+ }
0 commit comments