Skip to content

Jamie Royal - Solution to User Stories#50

Open
JamieRoyal wants to merge 2 commits intoGreggs-Digital:mainfrom
JamieRoyal:main
Open

Jamie Royal - Solution to User Stories#50
JamieRoyal wants to merge 2 commits intoGreggs-Digital:mainfrom
JamieRoyal:main

Conversation

@JamieRoyal
Copy link

Greggs Products API — Implementation Overview

This document explains the enhancements and architectural changes made to the Greggs Products API to fulfill the specified user stories.


Summary of Changes

1. Replacing Static Product List with Data Access Layer

Original Implementation:
The ProductController returned a random selection from a static, hardcoded product array inside the controller.

Change Made:
Introduced a proper data access layer (IDataAccess and ProductAccess implementation) that simulates fetching products from a database. The controller now depends on this data access abstraction and calls its List method to retrieve the latest products.

Why:
This satisfies User Story 1:
"As a Greggs Fanatic, I want to get the latest menu of products rather than a random static list."
It decouples data retrieval from controller logic and allows future extension to real databases.


2. Implementing Currency Conversion

Original Implementation:
Prices were always returned in GBP without any currency conversion.

Change Made:

  • Added a new SupportedCurrencies enum to define currencies.
  • Extended the Product model to support currency conversion via a ConvertPrice method, which converts prices from GBP to EUR (with a fixed exchange rate of 1 GBP = 1.11 EUR).
  • The controller accepts an optional query parameter convertTo (defaulting to EUR) and converts all product prices accordingly before returning them.

Error Handling:
If an unsupported currency is requested, the conversion fails gracefully — logging a warning and returning a BadRequest response indicating the unsupported currency.

Output DTO:
Introduced ProductDto to return product details, including original GBP price, converted price, and currency symbol.

Why:
This fulfills User Story 2:
"As a Greggs Entrepreneur, I want to get prices returned in Euros so I can expand our shop in Europe."
The implementation is extendable to support more currencies in the future.


3. Code Structure & Best Practices

Dependency Injection:
The data access layer is registered as a singleton service in Startup.cs and injected into the controller, promoting testability and separation of concerns.

Unit Testing:
Created unit tests covering:

  • Successful product retrieval and conversion to EUR.
  • Handling of unsupported currencies returning appropriate errors.
    The tests use mocks for the data access layer and logging, verifying both expected outputs and logging side effects.

Logging:
Currency conversion failures are logged with warnings to aid troubleshooting in production.

Swagger Integration:
Swagger is enabled to document and easily test the API endpoints.


How to Use

Get Products (default to EUR):
GET /product?pageStart=0&pageSize=5
Returns a paged list of products priced in EUR by default.

Get Products in GBP:
GET /product?convertTo=GBP
Returns products priced in GBP.

Unsupported Currency Example:
GET /product?convertTo=USD
Returns HTTP 400 Bad Request with an error message.


Summary

User Story Implementation Summary
1. Latest Menu Products Data access layer used to return paged product list.
2. Prices in Euros for Europe Shop Currency conversion logic in Product model, exposed via controller parameter. Handles unsupported currencies.

This is my code that fulfils the requirements set by the User Stories, with some additional Unit Testing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant