LogoRevali

HTTP Methods

HTTP methods define how your endpoints respond to requests

HTTP methods (also called verbs) define the behavior and purpose of your API endpoints. They tell clients what action they can perform and what to expect in return.

What Are HTTP Methods?#

Think of HTTP methods as instructions for your API:

  • GET - "Show me something" (retrieve data)
  • POST - "Create something new" (submit data)
  • PUT - "Replace this entirely" (update all data)
  • PATCH - "Update just this part" (partial update)
  • DELETE - "Remove this" (delete data)
  • SSE - "Stream data to me" (real-time updates)
  • WebSocket - "Let's chat" (bidirectional communication)

Available Methods#

Revali provides these method annotations:

AnnotationHTTP MethodPurposeWhen to Use
@Get() GET Retrieve data Reading resources, fetching lists
@Post() POST Create new data Creating resources, form submissions
@Put()PUTReplace entire resourceComplete updates
@Patch() PATCH Partial updates Modifying specific fields
@Delete()DELETERemove dataDeleting resources
@SSE() Server-Sent Events Real-time streaming Live updates, notifications
@WebSocket() WebSocket Bidirectional communication Chat, real-time collaboration

Basic Usage#

Simple Endpoint#

@Controller('api')
class ApiController {
  @Get()
  String getInfo() {
    return 'API is running';
  }
}

Result: Controller('api') + Get('') = GET /api

Custom Path#

@Controller('api')
class ApiController {
  @Get('status')
  String getStatus() {
    return 'All systems operational';
  }
}

Result: Controller('api') + Get('status') = GET /api/status

Path Parameters#

Path parameters let you create dynamic routes that accept variable values. They're defined using :parameterName syntax in your route paths.

How Path Parameters Work#

Path parameters create dynamic segments in your URLs:

  • :id matches any single segment (e.g., /users/123, /users/abc)
  • :userId matches any single segment (e.g., /users/john-doe)
  • Multiple parameters can be used in the same route

Basic Path Parameters#

@Controller('users')
class UsersController {
  @Get(':id')
  String getUser(@Param() String id) {
    return 'User ID: $id';
  }
}

Route: GET /users/:id
Examples:

  • /users/123id = "123"
  • /users/abcid = "abc"
  • /users/john-doeid = "john-doe"

Multiple Path Parameters#

@Controller('shops')
class ShopsController {
  @Get(':shopId/products/:productId')
  String getProduct(
    @Param() String shopId,
    @Param() String productId,
  ) {
    return 'Shop: $shopId, Product: $productId';
  }
}

Route: GET /shops/:shopId/products/:productId
Example: /shops/abc/products/xyzshopId = "abc", productId = "xyz"

Controller-Level Parameters#

You can define path parameters at the controller level to share them across all endpoints:

@Controller('shops/:shopId')
class ShopController {
  @Get('products')
  String getProducts(@Param() String shopId) {
    return 'Products for shop: $shopId';
  }

  @Get('orders')
  String getOrders(@Param() String shopId) {
    return 'Orders for shop: $shopId';
  }
}

Routes:

  • GET /shops/:shopId/products
  • GET /shops/:shopId/orders

Path Parameter Rules#

  • Always strings: Path parameters are always String type
  • Required: Path parameters are required - missing values cause 404 errors
  • URL encoded: Values are automatically URL decoded
  • Case sensitive: :userId:UserId

Custom HTTP Methods#

For special cases, you can create custom HTTP methods:

import 'package:revali_router/revali_router.dart';

final class CustomMethod extends Method {
  const CustomMethod([String? path]) : super('CUSTOM', path: path);
}

// Usage
@Controller('api')
class ApiController {
  @CustomMethod('special')
  String specialEndpoint() {
    return 'Custom method response';
  }
}

Endpoint: CUSTOM /api/special

Testing with curl#

curl -X CUSTOM http://localhost:8080/api/special

Response:

Custom method response

Complete Examples#

Here are practical examples for each HTTP method:

GET - Retrieve Data#

@Controller('users')
class UsersController {
  @Get()
  Future<List<User>> getUsers() async {
    return await userService.getAllUsers();
  }

  @Get(':id')
  Future<User> getUser(@Param() String id) async {
    return await userService.getUserById(id);
  }
}

Endpoints:

  • GET /users - Get all users
  • GET /users/:id - Get specific user

POST - Create Data#

@Controller('users')
class UsersController {
  @Post()
  Future<User> createUser(@Body() CreateUserRequest request) async {
    return await userService.createUser(request);
  }
}

Endpoint: POST /users - Create new user

PUT - Replace Entire Resource#

@Controller('users')
class UsersController {
  @Put(':id')
  Future<User> updateUser(
    @Param() String id,
    @Body() UpdateUserRequest request,
  ) async {
    return await userService.replaceUser(id, request);
  }
}

Endpoint: PUT /users/:id - Replace entire user

PATCH - Partial Update#

@Controller('users')
class UsersController {
  @Patch(':id')
  Future<User> patchUser(
    @Param() String id,
    @Body() PatchUserRequest request,
  ) async {
    return await userService.partialUpdateUser(id, request);
  }
}

Endpoint: PATCH /users/:id - Update specific fields

DELETE - Remove Data#

@Controller('users')
class UsersController {
  @Delete(':id')
  Future<void> deleteUser(@Param() String id) async {
    await userService.deleteUser(id);
  }
}

Endpoint: DELETE /users/:id - Delete user

SSE - Server-Sent Events#

@Controller('notifications')
class NotificationsController {
  @SSE('live')
  Stream<String> liveNotifications() async* {
    while (true) {
      yield 'Notification: ${DateTime.now()}';
      await Future.delayed(Duration(seconds: 1));
    }
  }
}

Endpoint: GET /notifications/live - Stream live notifications

WebSocket - Bidirectional Communication#

@Controller('chat')
class ChatController {
  @WebSocket('room/:roomId')
  Stream<String> chatRoom(@Param() String roomId) async* {
    // Handle WebSocket connection
    yield 'Connected to room: $roomId';
  }
}

Endpoint: WebSocket /chat/room/:roomId - Real-time chat

What's Next?#

Now that you understand HTTP methods, explore these related topics:

  1. Binding - Learn how to extract data from requests
  2. Pipes - Transform and validate request data
  3. Controllers - Organize your endpoints effectively

Ready to learn about data binding? Let's explore how to extract data from requests!