4. REST API with Web API Technology¶
You may earn 4 points by completing this exercise.
Use GitHub Classroom to get your git repository. You can find the invitation link in Moodle. Clone the repository created via the link. It contains a skeleton and the expected structure of your submission. After completing the exercises and verifying them, commit and push your submission.
The required software and tools for the solution can be found here.
Exercise 0: Neptun code¶
As a first step, enter your Neptun code into the neptun.txt
file located in the root folder.
Exercise 1: Simple query and OpenAPI documentation (2 points)¶
In the created and cloned repository, you'll find the initial code structure. Open it with Visual Studio and start the project. The basic program provides an empty solution. A console application should be started that hosts the web application. Try it out (while the program is running): open http://localhost:5000/api/product in your browser, where you should see the list of products in JSON format.
Check the available code.
- The
Startup.cs
initializes the application. This is an ASP.NET Core web application. - For simplicity, there is no database access in the application. The
ProductRepository
provides data to be used for testing. - The
ProductsController
instantiates theIProductRepository
using dependency injection.
Tasks:
Simple Query¶
-
In the
DAL.ProductRepository
class, replace the value of the field namedNeptun
with your Neptun code. The string value should consist of 6 characters from your Neptun code.IMPORTANT
A screenshot must be taken of the modified data, so this step is important.
-
Create an API endpoint to check if a product with a given id exists. We will send a
HEAD
HTTP request to the/api/product/{id}
URL for the query. The response should be HTTP 200 or 404 (without any extra content/body, only the response code is required).
OpenAPI Documentation¶
OpenAPI (formerly known as Swagger) is a documentation tool for REST APIs. Its purpose is similar to that of WSDL used for Web Services: to describe the API services in a standardized format. After completing the previous tasks, create an OpenAPI specification and documentation for the REST API description.
-
To complete the solution, follow the official Microsoft documentation: https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle
- Make sure to use the Swashbuckle option.
- The
swagger.json
should be generated by the application itself (you don't need to write it manually), and it should be accessible at/swagger/v1/swagger.json
. - Also set up the Swagger UI, which should be accessible at
/neptun
. You can achieve this by configuring theRoutePrefix
in theUseSwaggerUI
setup. Your Neptun code should be the prefix in all lowercase. - (You do not need to deal with the "Customize and extend" section or other customizations.)
-
Start the web application and check the
swagger.json
at http://localhost:5000/swagger/v1/swagger.json, and try out the SwaggerUI at http://localhost:5000/neptun. -
Test the "Try it out" feature of SwaggerUI: it actually sends the request to the web application, and you can see the real response.
-
Create the API endpoint that returns the desired product (
Product
) based on its ID; the request should be of typeGET
to the/api/product/{id}
URL, and the response should either be 200 with the data or 404 if no such item exists. Verify this using SwaggerUI.
SUBMISSION
Upload the modified source code. Make sure to note that the csproj
file has also been modified with the added NuGet package!
Take a screenshot of the Swagger UI displayed in the browser. Ensure that the URL shows that the SwaggerUI is served at the /neptun
path with your own Neptun code. Save the image as f1.png
and submit it as part of your solution!
Exercise 2: Product Operations (2 points)¶
The most common database operations related to products are inserting a new one, querying an existing product, modifying it, or deleting it, which are the CRUD (create, read, update, and delete) operations. We will create dedicated endpoints for these operations, allowing the API user to perform them. In this task, you need to implement the most common endpoints alongside the existing query.
-
Create an API endpoint that inserts a new product (
Product
) based on its ID; the request should be of typePOST
to the/api/product
address, expecting the newProduct
value in the request body, and the response should be either 201 or 409 if such an item already exists. -
Create an API endpoint that modifies a product (
Product
) based on its ID; the request should be of typePUT
to the/api/product/{id}
address, expecting the modifiedProduct
value in the request body, and the response should be either 204 with no content or 404 if such an item does not exist. -
Create an API endpoint that deletes a product (
Product
) based on its ID; the request should be of typeDELETE
to the/api/product/{id}
address, and the response should be either 204 with no content or 404 if such an item does not exist. -
Create an API endpoint that allows querying how many different products there are in total. (For example, to facilitate pagination, the frontend can calculate how many pages there will be.) This should also be a
GET
type request to the/api/product/-/count
address. The returned data should be an instance of theCountResult
class filled with the total count (in JSON format, of course).Why is there a
/-
part in the URL?To understand this, let's consider what the URL could be: we are curious about the number of products, so it could be
/api/product/
, but what comes after? It could be/api/product/count
. However, this "conflicts" with URLs like/api/product/123
, which is intended for querying a specific product. In practice, the two URLs could work together, because the product identifier is currently a number, so the framework recognizes that if the URL ends with/123
, it needs to execute the endpoint expecting a product ID, but if it ends with/count
, it should provide the count. But this only works if the ID is an integer. If the product identifier were text, there would be a problem. In such cases, a URL needs to be "invented" that does not collide. The/-
part indicates that there is not a product ID traveling there.Note: The URL - controller method identification is more complex in reality than described above. The ASP.NET Core framework matches controller methods to incoming request URLs in order of priority. We have the ability to influence this priority using the
[Http*]
attributesOrder
property.
SUBMISSION
Upload the modified source code.
Additionally, take a screenshot from Postman (or another testing tool) showing the result of a successful product retrieval. The image should display all details of the request and response (request type, URL, response code, response content). Your Neptun code must appear in the response. Save the image as f2.png
and submit it as part of your solution!
Exercise 3 optional: Partial Update of Product (0 points)¶
When modifying products, the previously used PUT
call has several disadvantages. PUT
is designed for updating the entire resource, meaning that to modify a product, the entire product must be sent. This is not only inefficient (for example, it requires retrieving and sending every existing property, regardless of their size) but also adds extra processing tasks. The PATCH
verb is designed to provide partial update capabilities, allowing only the properties that need to be modified to be sent.
In this task, you need to create an endpoint that allows for partial updates of products:
-
The request should be of type
PATCH
to the/api/product/{id}
URL, and the response should either be 204 if successful, or 404 if the item does not exist. -
Implement the endpoint in the
ProductController
class that performs the partial update. The type of the parameter received by the endpoint should be a strongly typed variant ofJsonPatchDocument
. During testing, ensure that only the values sent are changed (for example, if the sent object does not include stock, that should not change).
SUBMISSION
Upload the modified source code.
Additionally, take a screenshot from Postman (or another testing tool) showing the result of a successful partial modification. The image should display all details of the request and response (request type, URL, response code, response content). Your Neptun code must appear in the response. Save the image as f3.png
and submit it as part of your solution!