# Smart Recipe - Backend
SmartRecipe is a node.js application for creating meal plans. The existing API enables you to save entire recipes and single ingredients. Also, it offers you to automatically create completely random meal plans or ones that meet the following requirements:
- Amount of days
- Average calories per day
- Average meal preparation time
## About this guide
### Who is this documentation for?
This document is intended for people in the following roles:
- professional software engineers / computer scientists
- software engineering students
To understand this guide you need a basic understanding of:
- Node.js
- Express.js - REST API's
- Mongo DB
### What to expect
After this quick guide you'll have:
- running the application locally
- running a local database for the application
- a consumable [API](#rest-api-endpoints) running on localhost
- an overview of the [project structure](#project-structure) and [API](#rest-api-endpoints)
> This documentation explains only the backend application of the project.
## Install & Run
1. [Install Node.js + npm](https://nodejs.org/en/)
2. Clone the repository:
```bash
sudo git clone https://github.com/Osterpiegl/smartRecipe.git
```
3. Install dependencies:
```bash
cd smartRecipe/backend/
sudo npm i
```
4. [Download, install and run MongoDB](https://docs.mongodb.com/manual/administration/install-community/)
5. Start the application (automatically restarting on changes):
```bash
npm start
```
## Project structure
Most of the configurations lies in: `smartRecipe/backend/app.js` and `smartRecipe/backend/bin/www`.
The API is divided into the following parts:
| Name | Directory | Responsibility |
| ----------- | ----------------------------------- | ---------------------------- |
| Routes | smartRecipe/backend/api/routes | REST API Endpoints |
| Controllers | smartRecipe/backend/api/controllers | Request parsing + validation |
| Services | smartRecipe/backend/api/services | Business logic |
| Database | smartRecipe/backend/api/database | Database operations |
Whenever a client fetches an endpoint, the specific route gets triggered. The request then gets parsed & validated by the controllers. Then the corresponding service executes the business logic and queries the database with the database functions in `/backend/api/database`. This division makes the implementation modular and each part testable individually.
The structure used is inspired by Corey Cleary's ["Project structure for an Express REST API"](https://www.coreycleary.me/project-structure-for-an-express-rest-api-when-there-is-no-standard-way/).
## REST API Endpoints
Per default the server listens to `localhost:3000`. You can change the port in `smartRecipe/backend/bin/www`.
The API allways returns the result in JSON format.
### GET /api/foodplans
Returns foodplans that meet the given specifications.
#### Parameters (query string):
```javascript
plannedDays: Number, // for how many days the food plan should be (NUM)
avgDailyCalories: Number, // average daily calories (NUM)
avgMealReadyInTime: Number // average "ready in time" per meal (NUM)
```
### GET /api/randomRecipes
Returns recipes that meet the given specifications.
#### Parameters (query string):
```javascript
number: Number, // number of recipes
[isBreakfast: Boolean,] // if the recipes should be breakfasts
[calories: Number,] // calories per recipe
[mealReadyInTime: Number] // minutes per meal
```
### POST /api/recipe
Creates a new recipe by specifying the request-body as the following JSON object:
#### Body (JSON)
```javascript
{
recipe: {
name: String,
description: String,
servings: Number,
isBreakfast: Boolean,
calories: Number,
preparationTime: Number,
cookTime: Number,
readyInTime: Number,
ingredients: [
{
ingredient_id: String,
amount: Number
}, ...
]
}
}
```
### GET /api/units
Returns all units in the database.
#### Parameter (query string)
```javascript
[(limit: Number)];
```
### POST /api/unit
Creates a new unit by specifying the request-body as the following JSON object:
```javascript
{
name: String,
abbreviation: String
}
```
### GET /api/ingredients
Returns all ingredients in the database.
#### Parameter (query string)
```javascript
[(limit: Number)];
```
### POST /api/ingredient
Creates a new ingredient by specifying the request-body as the following JSON object:
```javascript
{
name: String,
unitId: String
}
```
<!--stackedit_data:
eyJoaXN0b3J5IjpbLTIxOTUxNDUwMyw1NjkyMzI5OTVdfQ==
-->