Endpoints

Endpoints in Spark are used to create API routes that return data (JSON, String, etc.) rather than full HTML pages. They are perfect for building REST APIs.

Basic Usage

To create an endpoint, annotate a class with `@Endpoint` and extend `SparkEndpoint`. You must implement the `handler` method.

@Endpoint(path: '/api/health', method: 'GET')
class HealthEndpoint extends SparkEndpoint {
  @override
  Future<String> handler(SparkRequest request) async {
    return 'OK';
  }
}

Request Body

To handle request bodies (e.g., JSON), extend `SparkEndpointWithBody<T>`. Spark will automatically parse the JSON body into your DTO class.

Your DTO needs an unnamed constructor with named parameters. The parameter names must match the JSON field names.

class CreateUserDto {
  final String name;
  final int age;

  CreateUserDto({required this.name, required this.age});
}

@Endpoint(path: '/api/users', method: 'POST')
class CreateUserEndpoint extends SparkEndpointWithBody<CreateUserDto> {
  @override
  Future<Response> handler(SparkRequest request, CreateUserDto body) async {
    // body is automatically parsed from JSON!
    return Response.ok('User ${body.name} created');
  }
}

Responses

The `handler` can return:

  • A primitive (String, Map, List) which will be automatically serialized.
  • A custom object (automatically serialized using its public fields).
  • A `Response` object for full control over status codes and headers.
  • A `Future` of any of the above.

Returning Custom Objects

Spark will automatically serialize your custom objects using their public fields. No `toJson()` method is required.

class UserResponse {
  final String name;
  final int age;

  UserResponse({required this.name, required this.age});
}

@Endpoint(path: '/api/me', method: 'GET')
class MeEndpoint extends SparkEndpoint {
  @override
  Future<UserResponse> handler(SparkRequest request) async {
    return UserResponse(name: 'John', age: 30);
  }
}

Middleware

You can add middleware to specific endpoints by overriding the `middleware` getter.

@Endpoint(path: '/api/protected', method: 'GET')
class ProtectedEndpoint extends SparkEndpoint {
  @override
  List<Middleware> get middleware => [AuthMiddleware()];

  @override
  Future<String> handler(SparkRequest request) async {
    return 'Secret Data';
  }
}