Strapi Find‐or‐Create API Documentation - KumarVikasGIT/my-strapi-docs GitHub Wiki

Strapi Find-or-Create API Documentation

Overview

This API provides "find-or-create" endpoints for various content types. Each endpoint:

  1. Searches for an existing record by its unique name/title field
  2. Returns the existing record if found
  3. Creates a new record with minimal required fields if not found
  4. Returns the ID and full object in a consistent response format

Common Response Structure

All endpoints return JSON with the following structure:

{
  "id": "number",
  "created": "boolean",
  "<content-type>": {
    // Full object properties
  }
}
  • id: Database ID of the record
  • created: true if new record was created, false if existing record found
  • : The full object (genre, language, publication, series, or author)

1. Genre Endpoint

Find or Create Genre

  • URL: /api/genres/find-or-create
  • Method: GET
  • Query Parameter:
    • genreName (string, required)

Example Request

GET /api/genres/find-or-create?genreName=Science%20Fiction

Example Response

{
  "id": 5,
  "created": false,
  "genre": {
    "id": 5,
    "genreName": "Science Fiction",
    "genreDescription": null,
    "createdAt": "2025-08-05T12:34:56.000Z",
    "updatedAt": "2025-08-05T12:34:56.000Z"
  }
}

2. Language Endpoint

Find or Create Language

  • URL: /api/languages/find-or-create
  • Method: GET
  • Query Parameters:
    • languageName (string, required)
    • locale (string, optional, default: 'en')

Example Request

GET /api/languages/find-or-create?languageName=Spanish&locale=es

Example Response

{
  "id": 8,
  "created": true,
  "language": {
    "id": 8,
    "language": "Spanish",
    "createdAt": "2025-08-06T09:15:22.000Z",
    "updatedAt": "2025-08-06T09:15:22.000Z",
    "locale": "es"
  }
}

3. Publication Endpoint

Find or Create Publication

  • URL: /api/publications/find-or-create
  • Method: GET
  • Query Parameters:
    • publicationName (string, required)
    • imageId (number, optional)
    • publish (boolean, optional, default: true)

Example Request

GET /api/publications/find-or-create?publicationName=Penguin%20Books&imageId=123

Example Response

{
  "id": 12,
  "created": true,
  "publication": {
    "id": 12,
    "publicationName": "Penguin Books",
    "publicationDescription": null,
    "publicationImage": {
      "id": 123,
      "url": "/uploads/penguin_logo.jpg"
    },
    "createdAt": "2025-08-06T11:30:45.000Z",
    "updatedAt": "2025-08-06T11:30:45.000Z",
    "publishedAt": "2025-08-06T11:30:45.000Z"
  }
}

4. Series Endpoint

Find or Create Series

  • URL: /api/series/find-or-create
  • Method: GET
  • Query Parameters:
    • seriesTitle (string, required)
    • description (string, optional)
    • publish (boolean, optional, default: true)

Example Request

GET /api/series/find-or-create?seriesTitle=Harry%20Potter&description=Wizarding%20world%20series

Example Response

{
  "id": 15,
  "created": true,
  "series": {
    "id": 15,
    "seriesTitle": "Harry Potter",
    "seriesDescription": "Wizarding world series",
    "books": [],
    "createdAt": "2025-08-06T14:20:30.000Z",
    "updatedAt": "2025-08-06T14:20:30.000Z",
    "publishedAt": "2025-08-06T14:20:30.000Z"
  }
}

5. Author Endpoint

Find or Create Author

  • URL: /api/authors/find-or-create
  • Method: GET
  • Query Parameters:
    • authorName (string, required)
    • description (string, optional) - JSON string of blocks
    • website (string, optional)
    • avatarId (number, optional)
    • publish (boolean, optional, default: true)

Example Request

GET /api/authors/find-or-create?authorName=J.K.%20Rowling&website=https://jkrowling.com&avatarId=456&description=[{"type":"paragraph","children":[{"text":"British author"}]}]

Example Response

{
  "id": 20,
  "created": true,
  "author": {
    "id": 20,
    "authorName": "J.K. Rowling",
    "authorDescription": [
      {
        "type": "paragraph",
        "children": [
          {
            "text": "British author"
          }
        ]
      }
    ],
    "authorWebsite": "https://jkrowling.com",
    "authorAvatar": {
      "id": 456,
      "url": "/uploads/jk_rowling.jpg"
    },
    "createdAt": "2025-08-06T16:45:10.000Z",
    "updatedAt": "2025-08-06T16:45:10.000Z",
    "publishedAt": "2025-08-06T16:45:10.000Z"
  }
}

Error Handling

All endpoints return appropriate HTTP status codes with error details:

  • 400 Bad Request: Missing required parameter or invalid parameter format
  • 500 Internal Server Error: Unexpected server error

Error Response Format

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "genreName query parameter is required"
}

Authentication & Permissions

By default, these endpoints are publicly accessible. To secure them:

  1. Create API token in Strapi admin
  2. Include in request header:
    Authorization: Bearer <your-api-token>
    

Recommended Permissions

Content Type Permission
Genre find, create
Language find, create
Publication find, create
Series find, create
Author find, create

Rate Limiting

By default, no rate limiting is applied. To enable:

  1. Install koa-ratelimit:
npm install koa-ratelimit
  1. Create middleware in src/middlewares/rate-limit.js:
const rateLimit = require('koa-ratelimit');

module.exports = strapi => ({
  initialize() {
    strapi.app.use(rateLimit({
      driver: 'memory',
      db: new Map(),
      duration: 60000,
      errorMessage: 'Too many requests',
      id: (ctx) => ctx.ip,
      headers: {
        remaining: 'Rate-Limit-Remaining',
        reset: 'Rate-Limit-Reset',
        total: 'Rate-Limit-Total'
      },
      max: 100,
      disableHeader: false,
    }));
  },
});

Best Practices

  1. Case Sensitivity: Most searches are case-insensitive
  2. Caching: Implement client-side caching for better performance
  3. Bulk Operations: Use for individual records only (no bulk support)
  4. Validation: Always validate parameters before calling
  5. Error Handling: Implement retry logic for 500 errors
  6. Content Management: Use Strapi admin panel to manage created records

Integration Example (JavaScript)

async function findOrCreateGenre(name) {
  try {
    const response = await fetch(
      `/api/genres/find-or-create?genreName=${encodeURIComponent(name)}`,
      {
        headers: {
          'Authorization': `Bearer ${API_TOKEN}`
        }
      }
    );
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    return await response.json();
  } catch (error) {
    console.error('Error finding or creating genre:', error);
    return null;
  }
}

// Usage
const result = await findOrCreateGenre('Science Fiction');
if (result) {
  console.log(`Genre ID: ${result.id}`, 
              result.created ? '(Created)' : '(Existing)');
}

Troubleshooting

  1. "Service not found" errors:

    • Rebuild project: npm run build
    • Clear cache: rm -rf .cache
    • Check service registration in src/index.ts
  2. Missing required fields:

    • Verify all required parameters are provided
    • Check content type schema for required fields
  3. Media upload issues:

    • Ensure media files exist before referencing by ID
    • Verify user has permission to access media
  4. Draft/Publish issues:

    • Check if content type has draft/publish enabled
    • Verify publishedAt is set when creating records

Changelog

Version Date Changes
1.0.0 2025-08-06 Initial release
1.1.0 2025-08-10 Added locale support
1.2.0 2025-08-15 Added media upload support