Skip to content

restful api implementation

Chubo Zeko edited this page Jun 3, 2022 · 8 revisions

Important information for Deadline 3

‼️  This chapter should be completed by Deadline 3 (see course information at Lovelace)


📑  Chapter summary In this section you must implement a RESTful API. The minimum requirements are summarized in the Minimum Requirements section of the Project Work Assignment. If you do not meet the minimum requirements this section WILL NOT be evaluated.

CHAPTER GOALS

  • Implement a RESTful API
  • Write tests for the API

✔️     Chapter evaluation (max 20 points) You can get a maximum of 20 points after completing this section. More detailed evaluation is provided in the evaluation sheet in Lovelace.

RESTful API implementation

List of implemented resources

📑  Content that must be included in the section A list of all implemented resources. Consider that you do not need to implement every resource you initially planned.   The minimum requirements are summarized in the Minimum requirements section from the Project work assignment. Do not forget to include in the README.md file which is the path to access to your application remotely.

URI Resource Tree

api/ 
├── chefs/
│   └── {chef}
│       ├── cookbooks/
│       │   └── {cookbook}
│       └── recipes/
│           └── {recipe}
├── cookbooks/
│   └── {cookbook}
│       └── recipes/
│           └── {recipe}
├── recipes/
│   └── {recipe}
│       └── ingredients/
│           └── {ingredient}
└── ingredients/
    └── {ingredient}

Resources

✏️ List your resources here. You can use the table below for listing resources. You can also list unimplemented resources if you think they are worth mentioning

Resource name Resource url Resource description Supported Methods Implemented
All Chefs /api/chefs A collection of all the users (UserCollection) GET, POST Yes
Chef /api/chefs/{chef} A single user (UserItem) GET, PUT, DELETE Yes
Cookbooks by Chef /api/chefs/{chef}/cookbooks/ A collection of all the cookbooks created by a specific user (CookbookCollection) GET, POST Yes
Cookbook by Chef /api/chefs/{chef}/cookbooks/{cookbook} A cookbook of a specific user (CookbookItem) GET, PUT, DELETE Yes
Recipes by Chef /api/chefs/{chef}/recipes/ A collection of all the recipes created by a specific user (RecipeCollection) GET, POST Yes
Recipe by Chef /api/chefs/{chef}/recipes/{recipe} A recipe created by a specific user (RecipeItem) GET, PUT, DELETE Yes
All Cookbooks /api/cookbooks/ A collection of all cookbooks (CookbookCollection) GET Yes
Recipes in a Cookbook /api/cookbooks/{cookbook}/recipes A collection of all recipes in a cookbook (CookbookRecipesCollection) GET, POST Yes
Recipe in a Cookbook /api/cookbooks/{cookbook}/recipes/{recipe} A collection of all cookbooks (CookbookRecipesItem) GET, DELETE Yes
All Recipes /api/recipes/ A collection of all recipes (RecipeCollection) GET Yes
Recipe /api/recipes/{recipe} A single recipe (RecipeItem) GET Yes
Ingredients from Recipe /api/recipes/{recipe}/ingredients/ A collection of the ingredients used in a specific recipe (RecipeIngredientCollection) GET, POST Yes
Ingredient from Recipe /api/recipes/{recipe}/ingredients/{ingredient} An ingredient used in a specific recipe (RecipeIngredientItem) GET, PUT, DELETE Yes
All Ingredients /api/ingredients/ A collection of all available ingredients (IngredientCollection) GET, POST Yes
Ingredient /api/ingredients/{ingredient} A single ingredient (IngredientItem) GET, PUT, DELETE Yes

Basic implementation

💻     TODO: SOFTWARE TO DELIVER IN THIS SECTION The code repository must contain:
  1. The source code for the RESTful API 
  2. The external libraries that you have used
  3. We recommend to include a set of scripts to setup and run your server
  4. A database file or the necessary files and scripts to automatically populate your database.
  5. A README.md file containing:
    • Dependencies (external libraries)
    • How to setup the framework.
    • How to populate and setup the database.
    • How to setup (e.g. modifying any configuration files) and run your RESTful API.
    • The URL to access your API (usually nameofapplication/api/version/)=> the path to your application.
NOTE: Your code MUST be clearly documented. For each public method/function you must provide: a short description of the method, input parameters, output parameters, exceptions (when the application can fail and how to handle such fail).  In addition should be clear which is the code you have implemented yourself and which is the code that you have borrowed from other sources. Always provide a link to the original source. This includes links to the course material.

✏️ You do not need to write anything in this section, just complete the implementation.


RESTful API testing

💻     TODO: SOFTWARE TO DELIVER IN THIS SECTION The code repository must contain:
  1. The code to test your RESTful API (Functional test)
    • The code of the test MUST be commented indicating what you are going to test in each test case.
    • The test must include values that force error messages
  2. The external libraries that you have used
  3. We recommend to include a set of scripts to execute your tests.
  4. A database file or the necessary files and scripts to automatically populate your database.
  5. A README.md file containing:
    • Dependencies (external libraries)
    • Instructions on how to run the different tests for your application.
Do not forget to include in the README.md the instructions on how to run your tests. Discuss briefly which were the main errors that you detected thanks to the functional testing.

Remember that you MUST implement a functional testing suite. A detailed description of the input / output in the a REST client plugin.

In this section it is your responsibility that your API handles requests correctly. All of the supported methods for each resource should work. You also need to show that invalid requests are properly handled, and that the response codes are correct in each situation.


✏️ You do not need to write anything in this section, just complete the implementation.


REST conformance

📑  Content that must be included in the section Explain briefly how your API meets REST principles. Focus specially in these three principles: Addressability, Uniform interface, and Statelessness. Provide examples (e.g. how does each HTTP method work in your API). Note that Connectedness will be addressed in Deadline 4.

✏️ EatHelp conforms to the REST principles of Addressability, Uniform interface, and Statelessness. This is described in detail in this section.

  1. Addressability: Each resource has a particular URI. Whenever a client requests a particular resource from EatHelp, such as retrieving all the chefs, then they can use an HTTP GET method to get the requested information from the server using the /api/chefs URI.

  2. Uniform Interface: Uniform interface is the key differentiator that makes an API RESTful. Nowadays, the ubiquity of client devices either through laptops, mobile phones, desktops, etc., has increased, which makes it necessary that the clients can receive requests on any device in the same way. In a nutshell, different types of software applications should be able to interact in a uniform way with the server. The four elements of the Uniform Interface principle are implemented as discussed below:

    1. Identification of resources: The resources that a client requests have a particular URI identifier. E.g. To retrieve all recipes from a particular chef, we would use /api/chefs/{chef}/recipes, where {chef} is the unique identifier (id) of the chef.
    2. Manipulations of resources through representations: The client receives a response that is represented in a JSON format. E.g.
    {
        "cookbook_id": 2,
        "name": "Super Meals",
        "user_id": 3,
        "description": "Recipes for busy Superheroes"
    }
    1. Self-descriptive messages of each request: A server does not store any information about the requested resource by the client. Therefore, the client needs to send a particular description each time with a request. Like a resource named ‘All Chefs’ with URL identifier ‘/api/chefs’, has a resource description, ‘A collection of all the users (UserCollection).’
    2. HATEOAS (Hypermedia as the engines of the application state): We need to implement Hypermedia concepts by including links for each response so that the client can discover other resources easily. In this way, the implementation of generalizability has been achieved so that every kind of client can access the resources in a same way.
  3. Statelessness: The concept of statelessness instructs that the server should not store any information about the session data related to the client. When a client sends a request to access any resource, everything that the server needs to respond to that requested resource is included in the request as parameters, and the server does not need to get those parameters separately. The state during a particular request is stored within the request sent by the client and the server understands the nature of the request and responds accordingly. Whereas the client can store the information about the session in its own context. This is advantageous in terms of scalability because there is no burden of inter-server interactions, and visibility is increased because there are no extra parameters added to the request from the server-side.


Extras

📑  Details on extra features This section lists the additional features that will be graded as part of the API but are not required. In addition to implementing the feature you are also asked to write a short description for each.

URL Converters

📑  Fill this section if you used URL converters Write a short rationale of how URL converters are used, including your thoughts on the possible trade-offs. Go through all URL parameters in your API and describe whether they use a converter, what property is used for converting, or why it's not using a converter.

✏️ URL converters are used in our resource URLs to convert the parameters to the format needed to identify the resource from the database. We used the default converters used in Python, being the Integer converter. We decided to use the resource models' IDs as the parameters in the URL as they were unique to each resource item in the database. The converters were used on the following resource items:

  • UserItem (/chefs/<int:chef>)
  • CookbookItem (/chefs/<int:chef>/cookbooks/<int:cookbook>)
  • RecipeItem (/recipes/<int:recipe>)
  • RecipeIngredientItem (/recipes/<int:recipe>/ingredients/<int:r_ingredient>)
  • IngredientItem (/ingredients/<int:ingredient>)

We did consider using a String converter for the UserItem resource by using the username of the user/chef instead of the user_id. This may have been a better solution, since the username is also a unique field, and it would increase the readability of the URL.


Schema Validation

📑  Fill this section if you used JSON schema validation Write a short description of your JSON schemas, including key decision making for choosing how to validate each field.

✏️ The JSON schema validation was used in all the models to validate the incoming requests and provide information on the required properties. It is a good way to ensure the data from the response body is in the correct data type and format, and this eases the process of appending and updating the database. The static json_schema methods are mainly utilized for the body of the POST and PUT requests. For each schema, we decided to include the properties of the non-nullable fields of the model to ensure that a value was passed for those fields. These schemas can be found in the models.py file.


Caching

📑  Fill this section if you implemented server side caching Explain your caching decisions here. Include an explanation for every GET method in your API, explaining what is cached (or why it is not cached), and how long is it cached (and why). If you are using manual cache clearing, also explain when it happens.

✏️

Caching was used in the IngredientItem and UserItem resources because those are the resources that wouldn't need to be changed or updated regularly once they are added. We used a SimpleCache type of cache because it uses a local Python dictionary for caching, and our resources utilize a similar dictionary data structure to store the resource model data.

  • IngredientItem (with its collective IngredientCollection) = uses cache in GET method

    • The IngredientItem is a model that contains the name of the ingredient (which is unique) and its id.
    • Based on that, the recipe ingredients can be created using the ingredient_id, and updated without altering the IngredientItem resource itself.
    • With that logic, the IngredientItem can be cached because it is the least likely resource to be changed or updated often.
  • UserItem (with its collective UserCollection) = uses cache in GET method

    • Similar to the IngredientItem, the UserItem resource are unlikely to be altered from the database, so they can easily be accessed from the cache instead of constantly retrieving their unchanged data.
  • CookbookItem (with its collective CookbookCollection) = does NOT use cache in GET method

    • The state of the cookbooks could change whenever a new cookbook is added or removed, or when recipes are added or removed from a particular cookbook.
  • RecipeItem (with its collective RecipeCollection) = does NOT use cache in GET method

    • The recipes are constantly manipulated in this API, as they have several fields that can be updated.
    • The same recipe in a different cookbook may be altered to a user's preference or improved.
  • RecipeIngredientItem (with its collective RecipeIngredientCollection) = does NOT use cache in GET method

    • The recipe ingredients do not need to be cached because although they are unique within a specific recipe, there can be recipe ingredients which have the same amount, unit and ingredient.
    • Perhaps the recipe ingredients of the same recipe in a different cookbook could be altered according to their calorie intake or removed to change the meal type.
  • CookbookRecipesItem (with its collective CookbookRecipesCollection) = does NOT use cache in GET method

    • This resource only contains the cookbook_id and recipe_id which are used to connect the recipes to cookbooks.
    • The GET method would mainly be used to see the many-to-many relationships between the two resources, so it may not be necessary to add it to the cache.

Authentication

📑  Fill this section if you implemented authentication Explain your authentication scheme here. Describe the authentication requirements for each resource in your API, and your reasoning for the decisions. In addition, provide a plan for how API keys will be distributed, even if the distribution is not currently implemented.

✏️

API authentication was not implemented at the moment since we don’t require session keys for user logins or API keys to restrict client access to certain API resources.


Resources allocation

Task Student Estimated time
Basic Implementation Chubo Zeko 18 hrs
URL Converters, Schema Validation Hamza Abdulla 2 hrs
Wiki Documentation Sehrish Khan 6 hrs