#корзина
Ключевые моменты
- В этом проекте мы будем работать с умом. Это означает, что мы выбираем по одному объекту, например пользователю, книге, блогу и т. д. за раз. Мы прорабатываем эту особенность. Шаги будут следующими:
- Создаем его модель.
- Мы создаем его API.
- Мы тестируем эти API.
- Мы развертываем эти API.
- Мы интегрируем эти API с интерфейсом.
- Мы повторим шаги с шага 1 по шаг 5 для каждой функции в этом проекте.
- Этот проект разделен на 4 функции, а именно «Пользователь», «Продукт», «Корзина» и «Заказ». Вам нужно работать над одной функцией одновременно. Как только это будет выполнено в соответствии с вышеупомянутыми шагами. Вам будет предложено перейти к следующей функции.
- В этом проекте мы меняем способ отправки токена с запросом. Вместо использования специального ключа заголовка, такого как x-api-key, вам необходимо использовать заголовок авторизации и отправить токен JWT в качестве токена носителя.
- Создайте групповую базу данных
groupXDatabase . Вы можете очистить ранее использованную базу данных и возобновить ее. - На этот раз каждая группа должна иметь одну ветку git . Координируйте свои действия, следя за тем, чтобы каждый следующий брал код, который последним ввел товарищ по команде. Ваша ветка будет проверена в рамках демо-версии. Имя ветки должно соответствовать соглашению об именах
project/productsManagementGroupX - Следуйте соглашениям об именах точно так, как указано.
ФУНКЦИЯ I — Пользователь
Модели
{
fname : {string, mandatory},
lname : {string, mandatory},
email : {string, mandatory, valid email, unique},
profileImage : {string, mandatory}, // s3 link
phone : {string, mandatory, unique, valid Indian mobile number},
password : {string, mandatory, minLen 8, maxLen 15}, // encrypted password
address : {
shipping : {
street : {string, mandatory},
city : {string, mandatory},
pincode : {number, mandatory}
},
billing : {
street : {string, mandatory},
city : {string, mandatory},
pincode : {number, mandatory}
}
},
createdAt : {timestamp},
updatedAt : {timestamp}
} Пользовательские API
Почта/регистрация
- Создайте пользовательский документ из тела запроса. Тело запроса должно содержать изображение.
- Загрузите изображение в корзину S3 и сохраните его общедоступный URL-адрес в документе пользователя.
- Сохраните пароль в зашифрованном формате. (используйте bcrypt)
- Формат ответа
- В случае успеха — вернуть статус HTTP 201. Также вернуть пользовательский документ. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
{
" status " : true,
" message " : " User created successfully " ,
" data " : {
" fname " : " John " ,
" lname " : " Doe " ,
" email " : " [email protected] " ,
" profileImage " : " https://classroom-training-bucket.s3.ap-south-1.amazonaws.com/user/copernico-p_kICQCOM4s-unsplash.jpg " ,
" phone " : 9876543210,
" password " : " $2b$10$DpOSGb0B7cT0f6L95RnpWO2P/AtEoE6OF9diIiAEP7QrTMaV29Kmm " ,
" address " : {
" shipping " : {
" street " : " MG Road " ,
" city " : " Indore " ,
" pincode " : 452001
},
" billing " : {
" street " : " MG Road " ,
" city " : " Indore " ,
" pincode " : 452001
}
},
" _id " : " 6162876abdcb70afeeaf9cf5 " ,
" createdAt " : " 2021-10-10T06:25:46.051Z " ,
" updatedAt " : " 2021-10-10T06:25:46.051Z " ,
" __v " : 0
}
} Почта/логин
- Разрешить пользователю войти в систему, используя свой адрес электронной почты и пароль.
- При успешной попытке входа в систему верните идентификатор пользователя и токен JWT, содержащий идентификатор пользователя, exp, iat.
ПРИМЕЧАНИЕ. Текст ответа немного изменился. Помимо токена JWT, вам также следует вернуть идентификатор пользователя.
- Формат ответа
- В случае успеха — вернуть статус HTTP 200 и токен JWT в теле ответа. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
{
" status " : true,
" message " : " User login successfull " ,
" data " : {
" userId " : " 6165f29cfe83625cf2c10a5c " ,
" token " : " eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MTYyODc2YWJkY2I3MGFmZWVhZjljZjUiLCJpYXQiOjE2MzM4NDczNzYsImV4cCI6MTYzMzg4MzM3Nn0.PgcBPLLg4J01Hyin-zR6BCk7JHBY-RpuWMG_oIK7aV8 "
}
} GET /user/:userId/profile (требуется аутентификация)
- Разрешить пользователю получать информацию о своем профиле.
- Убедитесь, что идентификатор пользователя в параметре URL и токене одинаковый.
- Формат ответа
- В случае успеха — возвращает статус HTTP 200 и возвращает пользовательский документ. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
{
" status " : true,
" message " : " User profile details " ,
" data " : {
" address " : {
" shipping " : {
" street " : " MG Road " ,
" city " : " Indore " ,
" pincode " : 452001
},
" billing " : {
" street " : " MG Road " ,
" city " : " Indore " ,
" pincode " : 452001
}
},
" _id " : " 6162876abdcb70afeeaf9cf5 " ,
" fname " : " John " ,
" lname " : " Doe " ,
" email " : " [email protected] " ,
" profileImage " : " https://classroom-training-bucket.s3.ap-south-1.amazonaws.com/user/copernico-p_kICQCOM4s-unsplash.jpg " ,
" phone " : 9876543210,
" password " : " $2b$10$DpOSGb0B7cT0f6L95RnpWO2P/AtEoE6OF9diIiAEP7QrTMaV29Kmm " ,
" createdAt " : " 2021-10-10T06:25:46.051Z " ,
" updatedAt " : " 2021-10-10T06:25:46.051Z " ,
" __v " : 0
}
} PUT /user/:userId/profile (требуется аутентификация и авторизация)
- Разрешить пользователю обновлять свой профиль.
- Пользователь может обновить все поля
- Убедитесь, что идентификатор пользователя в параметре URL и токене одинаковый.
- Формат ответа
- В случае успеха — вернуть статус HTTP 200. Также вернуть обновленный документ пользователя. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
{
" status " : true,
" message " : " User profile updated " ,
" data " : {
" address " : {
" shipping " : {
" street " : " MG Road " ,
" city " : " Delhi " ,
" pincode " : 110001
},
" billing " : {
" street " : " MG Road " ,
" city " : " Indore " ,
" pincode " : 452010
}
},
" _id " : " 6162876abdcb70afeeaf9cf5 " ,
" fname " : " Jane " ,
" lname " : " Austin " ,
" email " : " [email protected] " ,
" profileImage " : " https://classroom-training-bucket.s3.ap-south-1.amazonaws.com/user/laura-davidson-QBAH4IldaZY-unsplash.jpg " ,
" phone " : 9876543210,
" password " : " $2b$10$jgF/j/clYBq.3uly6Tijce4GEGJn9EIXEcw9NI3prgKwJ/6.sWT6O " ,
" createdAt " : " 2021-10-10T06:25:46.051Z " ,
" updatedAt " : " 2021-10-10T08:47:15.297Z " ,
" __v " : 0
}
} Примечание. Bcrypt Отправить данные формы
ФУНКЦИЯ II — Продукт
Модели
{
title : {string, mandatory, unique},
description : {string, mandatory},
price : {number, mandatory, valid number/decimal},
currencyId : {string, mandatory, INR},
currencyFormat : {string, mandatory, Rupee symbol},
isFreeShipping : {boolean, default: false},
productImage : {string, mandatory}, // s3 link
style : {string},
availableSizes : {array of string, at least one size, enum["S", "XS","M","X", "L","XXL", "XL"]},
installments : {number},
deletedAt : {Date, when the document is deleted},
isDeleted : {boolean, default: false},
createdAt : {timestamp},
updatedAt : {timestamp},
} API продуктов ( аутентификация не требуется )
ПОСТ /продукты
- Создайте документ продукта из тела запроса.
- Загрузите изображение продукта в корзину S3 и сохраните общедоступный URL-адрес изображения в документе.
- Формат ответа
- В случае успеха — вернуть статус HTTP 201. Также вернуть документ о продукте. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
ПОЛУЧИТЬ /продукты
- Возвращает все продукты в коллекции, которые не были удалены.
- Фильтры
- Размер (ключом для этого фильтра будет «размер»)
- Название продукта (ключом для этого фильтра будет «имя»). Вы должны вернуть все продукты, название которых содержит подстроку, полученную в этом фильтре.
- Цена: больше или меньше определенного значения. Ключами являются «priceGreaterThan» и «priceLessThan».
ПРИМЕЧАНИЕ. Для ценового фильтра запрос может содержать оба или любой из ключей. Например, запрос в запросе может выглядеть так: {priceGreaterThan: 500, PriceLessThan: 2000 } или просто {priceLessThan: 1000 }).
- Сортировать
- Сортировка по цене товара по возрастанию или убыванию. Пара ключ-значение будет выглядеть как {priceSort: 1} или {priceSort: -1}, например /products?size=XL&name=Nit%20grit.
- Формат ответа
- В случае успеха — вернуть HTTP-статус 200. Также вернуть документы на продукт. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
GET /products/:productId
- Возвращает сведения о продукте по идентификатору продукта
- Формат ответа
- В случае успеха — вернуть HTTP-статус 200. Также вернуть документы на продукт. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
PUT /продукты/:идентификатор продукта
- Обновляет продукт, изменяя хотя бы одно или все поля.
- Проверьте, существует ли идентификатор продукта (должен иметь значение isDeleted false и присутствовать в коллекции). Если это не так, верните HTTP-статус 404 с таким телом ответа.
- Формат ответа
- В случае успеха — вернуть статус HTTP 200. Также вернуть обновленный документ продукта. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
УДАЛИТЬ /products/:productId
- Удаляет продукт по идентификатору продукта, если он еще не удален.
- Формат ответа
- В случае успеха — вернуть статус HTTP 200. Ответом должен быть объект JSON, подобный этому.
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
ФУНКЦИЯ III — Корзина
Модели
{
userId : {ObjectId, refs to User, mandatory, unique},
items : [{
productId : {ObjectId, refs to Product model, mandatory},
quantity : {number, mandatory, min 1}
}],
totalPrice : {number, mandatory, comment: "Holds total price of all the items in the cart"},
totalItems : {number, mandatory, comment: "Holds total number of items in the cart"},
createdAt : {timestamp},
updatedAt : {timestamp},
} API корзины ( требуется аутентификация в виде заголовка авторизации — токена-носителя )
POST /users/:userId/cart (Добавить в корзину)
- Создайте корзину для пользователя, если она не существует. В противном случае добавьте товар(ы) в корзину.
- Получите идентификатор корзины в теле запроса.
- Получите ProductId в теле запроса.
- Убедитесь, что корзина существует.
- Добавьте товар(ы) для пользователя в корзину.
- Убедитесь, что идентификатор пользователя в параметрах и токене JWT совпадают.
- Убедитесь, что пользователь существует
- Убедитесь, что продукты действительны и не удалены.
- Получите подробную информацию о продукте в теле ответа.
- Формат ответа
- В случае успеха — вернуть статус HTTP 201. Также вернуть документ корзины. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
PUT /users/:userId/cart (Удалить товар/Уменьшить количество товара из корзины)
- Обновляет корзину, уменьшая количество товара на 1 или удаляя товар из корзины.
- Получите идентификатор корзины в теле запроса.
- Получите ProductId в теле запроса.
- Получите ключ «removeProduct» в теле запроса.
- Убедитесь, что корзина существует.
- Ключ «removeProduct» указывает, следует ли удалить продукт ({removeProduct: 0}) или его количество должно быть уменьшено на 1 ({removeProduct: 1}).
- Убедитесь, что идентификатор пользователя в параметрах и токене JWT совпадают.
- Убедитесь, что пользователь существует
- Получите подробную информацию о продукте в теле ответа.
- Прежде чем обновлять корзину, проверьте, существует ли идентификатор продукта и не удален ли он.
- Формат ответа
- В случае успеха — вернуть HTTP-статус 200. Также вернуть обновленный документ корзины. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
ПОЛУЧИТЕ /users/:userId/cart
- Возвращает сводку корзины пользователя.
- Убедитесь, что корзина существует.
- Убедитесь, что идентификатор пользователя в параметрах и токене JWT совпадают.
- Убедитесь, что пользователь существует
- Получите подробную информацию о продукте в теле ответа.
- Формат ответа
- В случае успеха — вернуть HTTP-статус 200. Вернуть документ корзины. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
УДАЛИТЬ /users/:userId/cart
- Удаляет корзину для пользователя.
- Убедитесь, что корзина существует.
- Убедитесь, что идентификатор пользователя в параметрах и токене JWT совпадают.
- Убедитесь, что пользователь существует
- Удаление корзины означает, что массив товаров пуст, totalItems равен 0, totalPrice равен 0.
- Формат ответа
- В случае успеха — вернуть статус HTTP 204. Вернуть подходящее сообщение. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
ОСОБЕННОСТЬ IV — Заказ
Модели
{
userId : {ObjectId, refs to User, mandatory},
items : [{
productId : {ObjectId, refs to Product model, mandatory},
quantity : {number, mandatory, min 1}
}],
totalPrice : {number, mandatory, comment: "Holds total price of all the items in the cart"},
totalItems : {number, mandatory, comment: "Holds total number of items in the cart"},
totalQuantity : {number, mandatory, comment: "Holds total number of quantity in the cart"},
cancellable : {boolean, default: true},
status : {string, default: 'pending', enum[pending, completed, cancled]},
deletedAt : {Date, when the document is deleted},
isDeleted : {boolean, default: false},
createdAt : {timestamp},
updatedAt : {timestamp},
} API оформления заказа/заказа (требуется аутентификация и авторизация)
POST/users/:userId/orders
- Создать заказ для пользователя
- Убедитесь, что идентификатор пользователя в параметрах и токене JWT совпадают.
- Убедитесь, что пользователь существует
- Получите информацию о корзине в теле запроса
- Формат ответа
- В случае успеха — вернуть статус HTTP 200. Также вернуть документ заказа. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
PUT /users/:userId/orders
- Обновляет статус заказа
- Убедитесь, что идентификатор пользователя в параметрах и токене JWT совпадают.
- Убедитесь, что пользователь существует
- Получить идентификатор заказа в теле запроса
- Убедитесь, что заказ принадлежит пользователю
- Убедитесь, что отменить можно только отменяемый заказ. В противном случае отправьте соответствующее сообщение об ошибке и ответ.
- Формат ответа
- В случае успеха — вернуть HTTP-статус 200. Также вернуть обновленный документ заказа. Ответ должен быть таким объектом JSON
- При ошибке — возврат подходящего сообщения об ошибке с действительным кодом состояния HTTP. Ответ должен быть таким объектом JSON
Тестирование
- Чтобы протестировать эти API, создайте в Postman новую коллекцию под названием Project 5 Shopping Cart.
- У каждого API должен быть новый запрос в этой коллекции.
- Каждый запрос в коллекции должен быть правильно назван. Например, создать пользователя, создать продукт, получить продукты и т. д.
- Каждый член каждой команды должен иметь свои тесты в рабочем состоянии.
См. образец ниже 
Ответ
Структура успешного ответа
{
status : true,
message : ' Success ' ,
data : {
}
} Структура ответа на ошибку
{
status : false,
message : " "
} Коллекции
пользователи
{
_id : ObjectId("88abc190ef0288abc190ef02"),
fname : ' John ' ,
lname : ' Doe ' ,
email : ' [email protected] ' ,
profileImage : ' http://function-up-test.s3.amazonaws.com/users/user/johndoe.jpg ' , // s3 link
phone : 9876543210,
password : ' $2b$10$O.hrbBPCioVm237nAHYQ5OZy6k15TOoQSFhTT.recHBfQpZhM55Ty ' , // encrypted password
address : {
shipping : {
street : " 110, Ridhi Sidhi Tower " ,
city : " Jaipur " ,
pincode : 400001
}, {mandatory}
billing : {
street : " 110, Ridhi Sidhi Tower " ,
city : " Jaipur " ,
pincode : 400001
}
},
createdAt : " 2021-09-17T04:25:07.803Z " ,
updatedAt : " 2021-09-17T04:25:07.803Z " ,
} продукты
{
_id : ObjectId("88abc190ef0288abc190ef55"),
title : ' Nit Grit ' ,
description : ' Dummy description ' ,
price : 23.0,
currencyId : ' INR ' ,
currencyFormat : ' ₹ ' ,
isFreeShipping : false,
productImage : ' http://function-up-test.s3.amazonaws.com/products/product/nitgrit.jpg ' , // s3 link
style : ' Colloar ' ,
availableSizes : ["S", "XS","M","X", "L","XXL", "XL"],
installments : 5,
deletedAt : null,
isDeleted : false,
createdAt : " 2021-09-17T04:25:07.803Z " ,
updatedAt : " 2021-09-17T04:25:07.803Z " ,
} тележки
{
" _id " : ObjectId("88abc190ef0288abc190ef88"),
userId : ObjectId("88abc190ef0288abc190ef02"),
items : [{
productId : ObjectId("88abc190ef0288abc190ef55"),
quantity : 2
}, {
productId : ObjectId("88abc190ef0288abc190ef60"),
quantity : 1
}],
totalPrice : 50.99,
totalItems : 2,
createdAt : " 2021-09-17T04:25:07.803Z " ,
updatedAt : " 2021-09-17T04:25:07.803Z " ,
} заказы
{
" _id " : ObjectId("88abc190ef0288abc190ef88"),
userId : ObjectId("88abc190ef0288abc190ef02"),
items : [{
productId : ObjectId("88abc190ef0288abc190ef55"),
quantity : 2
}, {
productId : ObjectId("88abc190ef0288abc190ef60"),
quantity : 1
}],
totalPrice : 50.99,
totalItems : 2,
totalQuantity : 3,
cancellable : true,
status : ' pending '
createdAt : " 2021-09-17T04:25:07.803Z " ,
updatedAt : " 2021-09-17T04:25:07.803Z " ,
}