LogoSkills

serverpod:endpoint

Serverpod endpoint and service class generation

항ëŠĐë‚īėšĐ
Categorypetmedi-workflow
Complexitystandard
MCP Serversserena, context7

/serverpod:endpoint#

Context Framework Note: This behavioral instruction activates when Claude Code users type /serverpod:endpoint patterns.

Triggers#

  • When a new Serverpod API endpoint is needed
  • When backend business logic implementation is needed
  • Called in Step 2 of /feature:create orchestration

Context Trigger Pattern#

/serverpod:endpoint {feature_name} {entity_name} [--options]

Parameters#

ParameterRequiredDescriptionExample
feature_name ✅ Feature module name (snake_case) community, chat
entity_name ✅ Entity name (PascalCase) Post, Message
--type ❌ Endpoint type app, console, both (default: app)
--methods ❌ Methods to generate "getList, get, create, update, delete"

Behavioral Flow#

1. Analyze Existing Patterns#

Use Serena MCP to analyze existing endpoint patterns:
- backend/petmedi_server/lib/src/feature/community/endpoint/post_endpoint.dart
- backend/petmedi_server/lib/src/feature/community/service/post_service.dart

2. Follow Import Order (Required)#

// 1. Serverpod framework
import 'package:serverpod/server.dart';

// 2. Generated protocol (models)
import 'package:petmedi_server/src/generated/protocol.dart';

// 3. Feature internal services
import 'package:petmedi_server/src/feature/{feature}/service/{feature}_service.dart';

// 4. Common utilities
import 'package:petmedi_server/src/common/authenticated_mixin.dart';

3. Generate Endpoint Classes#

App Endpoint ({feature}_endpoint.dart):

/// {Feature} endpoint
///
/// - Provides list, single, create, update, delete functionality
/// - Accessible only to authenticated users
class {Feature}Endpoint extends Endpoint with AuthenticatedMixin {
  /// Retrieves the {entity} list.
  Future<{Entity}ListResponse> get{Entity}s(
    Session session, {
    int? limit,
    int? offset,
    {Entity}Category? category,
  }) async {
    return {Feature}Service.get{Entity}s(
      session,
      limit: limit ?? 20,
      offset: offset ?? 0,
      category: category,
    );
  }

  /// Creates a {entity}.
  Future<{Entity}> create{Entity}(
    Session session,
    {Entity}CreateRequest request,
  ) async {
    final user = await requireAuthenticatedUser(session);
    return {Feature}Service.create{Entity}(session, request, user.id!);
  }

  // ... remaining CRUD methods
}

Console Endpoint ({feature}_console_endpoint.dart):

/// {Feature} console endpoint (admin only)
class {Feature}ConsoleEndpoint extends Endpoint {
  @override
  bool get requireLogin => true;

  @override
  Set<Scope> get requiredScopes => {Scope.admin};

  /// Retrieves the full {entity} list (admin only).
  Future<List<{Entity}>> getAll{Entity}s(
    Session session, {
    int? limit,
    int? offset,
    bool includeDeleted = false,
  }) async {
    return {Feature}Service.getAll{Entity}sForAdmin(
      session,
      limit: limit,
      offset: offset,
      includeDeleted: includeDeleted,
    );
  }
}

4. Generate Service Class#

/// {Feature} business logic service
class {Feature}Service {
  /// Retrieves the {entity} list.
  static Future<{Entity}ListResponse> get{Entity}s(
    Session session, {
    required int limit,
    required int offset,
    {Entity}Category? category,
  }) async {
    try {
      final entities = await {Entity}.db.find(
        session,
        where: (t) {
          var condition = t.isDeleted.equals(false);
          if (category != null) {
            condition = condition & t.category.equals(category);
          }
          return condition;
        },
        orderBy: (t) => t.createdAt,
        orderDescending: true,
        limit: limit,
        offset: offset,
      );

      final total = await {Entity}.db.count(session, where: ...);

      return {Entity}ListResponse(
        items: entities,
        total: total,
        hasMore: offset + entities.length < total,
      );
    } on Exception catch (error, stackTrace) {
      session.log(
        '{Feature} list query failed: $error',
        exception: error,
        level: LogLevel.error,
        stackTrace: stackTrace,
      );
      rethrow;
    }
  }

  // ... remaining business logic
}

Output Files#

backend/petmedi_server/lib/src/feature/{feature_name}/
├── endpoint/
│   ├── {feature_name}_endpoint.dart       # App endpoint
│   └── {feature_name}_console_endpoint.dart  # Console endpoint (optional)
├── service/
│   └── {feature_name}_service.dart        # Business logic
└── validation/
    └── {feature_name}_validator.dart      # Input validation (optional)

Post-Generation Commands#

# Code generation (endpoint registration)
melos run backend:pod:generate

MCP Integration#

  • Serena: Analyze existing endpoint patterns, symbol search
  • Context7: Serverpod endpoint documentation reference

Examples#

Create post endpoint#

/serverpod:endpoint community Post --type both

Create chat endpoint#

/serverpod:endpoint chat Message --type app
  --methods  " getMessages, sendMessage, markAsRead "

Create admin dashboard endpoint#

/serverpod:endpoint dashboard Stats --type console
  --methods  " getOverview, getUserStats, getContentStats "

Reference Agent#

See ~/.claude/commands/agents/serverpod-endpoint-agent.md for detailed implementation rules

Core Rules Summary#

  1. Follow import order (Serverpod → Protocol → Feature → Utils)
  2. Use AuthenticatedMixin (for authenticated methods)
  3. Set permissions on Console endpoints (requireLogin, requiredScopes)
  4. Separate business logic into Services
  5. Error handling and logging (session.log)
  6. Apply soft delete pattern