Store Endpoints (/store, /stores)

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.