Basket Web API is a demo of a RESTful API for managing shopping cart contents, written in C#/ASP .NET Core. It uses HAL (Hypertext Application Language) convention for representing resources and links, making it easier to navigate to related resources.
- Authenticate a user (please use any username with password
demo
). The API uses Bearer JWT tokens. - Retrieve basket contents
- Add an item to the basket
- Retrieve item contents from the basket
- Update item quantity in the basket
- Remove an item from the basket
- Remove all items from the basket
- Resource access authorization - a user can't access baskets of other users
- Basket operations for unauthenticated users aren't supported
- Each authenticated user has a basket (and only one basket) - therefore baskets are identified by userid
- Items in the basket are identified by product id
- Adding another item with the same product id to the basket simply results in increasing of the quantity of existing item
- Only quantity can be updated in a basket item
- Product data is stubbed (test data is embedded in basket item contents for illustration purposes only)
- BasketApi - Basket REST API itself (ASP .NET Core Web API)
- BasketApiClient - sample .NET client simplifying calls to Basket API
- BasketApi.Contracts - data contracts, shared between the server and the client project
- BasketApi.IntegrationTests - test scenarios exercising the client making calls to the API
Users need to authenticate with the Token endpoint.
Any username is accepted by the token endpoint, as long as the password is demo
.
POST http://localhost:56128/api/token
Content-Type: application/json
{ "username": "someuser", "password": "demo}
Response:
<JWT token content>
or HTTP 401 if authentication wasn't successful.
_client.Authorize("someuser", "password")
Successful authentication stores the JWT token in client HTTP headers
Retrieves basket contents for currently authenticated user. GET http://localhost:56128/api/my/basket (Note: basket canonical URL is http://localhost:56128/api/users//basket) Authorization: Bearer Response:
{
"_links": {
"self": {
"href": "/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket",
"title": "basket"
},
"items": {
"href": "/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items",
"title": "items"
}
},
"id": "cc1edc35-cbc1-40dd-abdb-73604dcc9fab",
"items": [
{
"_embedded": {
"product": {
"_links": {
"self": {
"href": "http://api.contoso.com/products/91a63109-17f6-48aa-b942-366022abaa8e",
"title": "product"
}
},
"productId": "91a63109-17f6-48aa-b942-366022abaa8e",
"description": "Description of product 91a63109-17f6-48aa-b942-366022abaa8e",
"productImageUrl": "http://contoso.com/products/assets/91a63109-17f6-48aa-b942-366022abaa8e.png",
"price": 69.3242677810249
}
"_links": {
"self": {
"href": "/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items/61a63109-17f6-48aa-b942-366022abaa8d",
"title": "basket"
}
},
"productId": "61a63109-17f6-48aa-b942-366022abaa8d",
"quantity": 3
}
],
"totalPrice": 69.3242677810249
}
POST http://localhost:56128/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items
Authorization: Bearer
Content-Type: application/json
{ "productId": "61a63109-17f6-48aa-b942-366022abaa8d", "quantity": 3 }
Response: HTTP 201 Location: api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items/61a63109-17f6-48aa-b942-366022abaa8d
PUT http://localhost:56128/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items/61a63109-17f6-48aa-b942-366022abaa8d
Authorization: Bearer
Content-Type: application/json
{ "quantity": 3 }
Response: HTTP 200 if successful; HTTP 404 if item doesn't exist
GET http://localhost:56128/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items/61a63109-17f6-48aa-b942-366022abaa8d Authorization: Bearer
Response: HTTP 200 if successful; HTTP 404 if item doesn't exist
{
"_embedded": {
"product": {
"_links": {
"self": {
"href": "http://api.contoso.com/products/61a63109-17f6-48aa-b942-366022abaa8d",
"title": "product"
}
},
"productId": "61a63109-17f6-48aa-b942-366022abaa8d",
"description": "Description of product 61a63109-17f6-48aa-b942-366022abaa8d",
"productImageUrl": "http://contoso.com/products/assets/61a63109-17f6-48aa-b942-366022abaa8d.png",
"price": 75.5642617007551
}
},
"_links": {
"self": {
"href": "/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items/61a63109-17f6-48aa-b942-366022abaa8d",
"title": "basket"
}
},
"productId": "61a63109-17f6-48aa-b942-366022abaa8d",
"quantity": 3
}
GET http://localhost:56128/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items Authorization: Bearer
Response: HTTP 200
[
{
"_embedded": {
"product": {
"_links": {
"self": {
"href": "http://api.contoso.com/products/61a63109-17f6-48aa-b942-366022abaa8d",
"title": "product"
}
},
"productId": "61a63109-17f6-48aa-b942-366022abaa8d",
"description": "Description of product 61a63109-17f6-48aa-b942-366022abaa8d",
"productImageUrl": "http://contoso.com/products/assets/61a63109-17f6-48aa-b942-366022abaa8d.png",
"price": 16.8330286242222
}
},
"_links": {
"self": {
"href": "/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items/61a63109-17f6-48aa-b942-366022abaa8d",
"title": "basket"
}
},
"productId": "61a63109-17f6-48aa-b942-366022abaa8d",
"quantity": 3
},
{
"_embedded": {
"product": {
"_links": {
"self": {
"href": "http://api.contoso.com/products/91a63109-17f6-48aa-b942-366022abaa8e",
"title": "product"
}
},
"productId": "91a63109-17f6-48aa-b942-366022abaa8e",
"description": "Description of product 91a63109-17f6-48aa-b942-366022abaa8e",
"productImageUrl": "http://contoso.com/products/assets/91a63109-17f6-48aa-b942-366022abaa8e.png",
"price": 99.8433476313219
}
},
"_links": {
"self": {
"href": "/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items/91a63109-17f6-48aa-b942-366022abaa8e",
"title": "basket"
}
},
"productId": "91a63109-17f6-48aa-b942-366022abaa8e",
"quantity": 10
}
]
DELETE http://localhost:56128/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items/61a63109-17f6-48aa-b942-366022abaa8d Authorization: Bearer
Response: HTTP 200 if successful; HTTP 404 if item doesn't exist
DELETE http://localhost:56128/api/users/cc1edc35-cbc1-40dd-abdb-73604dcc9fab/basket/items Authorization: Bearer
Response: HTTP 200
BasketApiClient is a .NET library, which can be used for calling Basket Web API.
var client = new BasketApiClient(new Uri("http://localhost:56128"));
client.Authorize("someuser", "password")
Successful authentication stores the JWT token in client HTTP headers
var basket = client.GetOwnBasket();
Note: Each basket item has a URL to itself that can be used to perform some of the operations below. The basket item link can be obtained as follows:
var basketItemUrl = basket.Items[0].ExtractSelfLink();
Basket obtained from GetOwnBasket method is needed to delete all items from the basket:
var basketItemUrl = await _client.AddBasketItem(basket, basketItemToAdd);
URL obtained from the AddBasketItem method can be used to update an item:
await _client.UpdateBasketItem(basketItemUrl, basketItemToUpdate);
URL obtained from the AddBasketItem method can be used to update an item:
await _client.DeleteBasketItem(basketItemUrl);
Basket obtained from GetOwnBasket method is needed to delete all items from the basket:
await _client.ClearBasket(basket);
- A collection of Postman requests for Basket API - can be used for testing locally