How to Use the API - Store Endpoints (/store, /stores)

The Store Endpoints group books by their stores and allow basic CRUD operations at the store level. These endpoints let you list all stores, fetch a specific store, create new stores, and delete existing ones. Stores are persisted in SQLite through SQLAlchemy and exposed via Flask-RESTful resources.

Store Model Overview

The StoreModel maps to the stores table and relates each store to its books. Its json() method returns the storeโ€™s name and an array of associated books.

class StoreModel(db.Model):
    __tablename__ = 'stores'
    id     = db.Column(db.Integer, primary_key=True)
    name   = db.Column(db.String(80))
    books  = db.relationship('BookModel', lazy='dynamic')

    def json(self):
        return {
            'name': self.name,
            'books': [book.json() for book in self.books.all()]
        }
  • name: Unique store name
  • books: List of BookModel.json() outputs

Endpoint Summary ๐Ÿ“‹

Method Endpoint Description
GET /stores List all stores with their books
GET /store/{name} Fetch a store by name
POST /store/{name} Create a new store
DELETE /store/{name} Delete a store by name

GET /stores

Retrieves all stores in the system. Each store includes its name and an array of its books.

{
    "title": "List All Stores",
    "description": "Fetches every store along with its books.",
    "method": "GET",
    "baseUrl": "http://localhost:5000",
    "endpoint": "/stores",
    "headers": [],
    "queryParams": [],
    "pathParams": [],
    "bodyType": "none",
    "requestBody": "",
    "formData": [],
    "rawBody": "",
    "responses": {
        "200": {
            "description": "A list of stores.",
            "body": "{\n  \"stores\": [\n    {\n      \"name\": \"Downtown\",\n      \"books\": [\n        { \"title\": \"Flask 101\", \"price\": 29.99, \u2026 }\n      ]\n    }\n  ]\n}"
        }
    }
}

Note: No authentication is required.


GET /store/{name}

Looks up a single store by name. Returns the storeโ€™s details if found, otherwise a 404 error.

{
    "title": "Get Store by Name",
    "description": "Retrieves a specific store and its books.",
    "method": "GET",
    "baseUrl": "http://localhost:5000",
    "endpoint": "/store/{name}",
    "headers": [],
    "queryParams": [],
    "pathParams": [
        {
            "key": "name",
            "value": "Store name to search",
            "required": true
        }
    ],
    "bodyType": "none",
    "requestBody": "",
    "formData": [],
    "rawBody": "",
    "responses": {
        "200": {
            "description": "Store found.",
            "body": "{\n  \"name\": \"Downtown\",\n  \"books\": [ \u2026 ]\n}"
        },
        "404": {
            "description": "Store not found.",
            "body": "{\n  \"message\": \"Store not found\"\n}"
        }
    }
}

โœ… Uses StoreModel.find_by_name(name) to locate the store


POST /store/{name}

Creates a new store with the specified name. Rejects duplicates and handles database errors.

{
    "title": "Create Store",
    "description": "Creates a new store if the name is unique.",
    "method": "POST",
    "baseUrl": "http://localhost:5000",
    "endpoint": "/store/{name}",
    "headers": [
        {
            "key": "Content-Type",
            "value": "application/json",
            "required": false
        }
    ],
    "queryParams": [],
    "pathParams": [
        {
            "key": "name",
            "value": "New store name",
            "required": true
        }
    ],
    "bodyType": "none",
    "requestBody": "",
    "formData": [],
    "rawBody": "",
    "responses": {
        "201": {
            "description": "Store created successfully.",
            "body": "{\n  \"name\": \"Uptown\",\n  \"books\": []\n}"
        },
        "400": {
            "description": "Duplicate store name.",
            "body": "{\n  \"message\": \"A store with name 'Uptown' already exists.\"\n}"
        },
        "500": {
            "description": "Database error.",
            "body": "{\n  \"message\": \"An error occurred creating the store.\"\n}"
        }
    }
}
  • 400 if find_by_name returns a match
  • 500 on save_to_db() exception
{
    "title": "Unique Store Names",
    "content": "Each store name must be unique; creating a duplicate returns a 400 error.",
    "type": "",
    "filePath": "",
    "badges": []
}

DELETE /store/{name}

Deletes the specified store. Returns a confirmation message regardless of prior existence.

{
    "title": "Delete Store",
    "description": "Removes the store if it exists.",
    "method": "DELETE",
    "baseUrl": "http://localhost:5000",
    "endpoint": "/store/{name}",
    "headers": [],
    "queryParams": [],
    "pathParams": [
        {
            "key": "name",
            "value": "Store name to delete",
            "required": true
        }
    ],
    "bodyType": "none",
    "requestBody": "",
    "formData": [],
    "rawBody": "",
    "responses": {
        "200": {
            "description": "Always returns deletion acknowledgment.",
            "body": "{\n  \"message\": \"Store deleted\"\n}"
        }
    }
}
  • No 404 on missing store; always acknowledges deletion

By following these examples, you can seamlessly integrate store-level CRUD operations into your client or Postman collection. Each endpoint is self-contained and returns clear JSON responses for success and error cases.