lejard-h / chopper

Chopper is an http client generator using source_gen and inspired from Retrofit.
https://hadrien-lejard.gitbook.io/chopper
Other
713 stars 123 forks source link

Why method annotation are immutable? #536

Closed KeidsID closed 11 months ago

KeidsID commented 11 months ago

I mean Dio didn't force const for the request headers.

Dio(BaseOptions(
  baseUrl: 'https://api.themoviedb.org/$kTmdbApiVersion',
  headers: {"Authorization": "Bearer ${Env.tmdbAccToken}"},
));

Steps to Reproduce

  1. SDKs & packages Versions

    environment:
     sdk: ^3.0.0 # v3.0.2
     flutter: ^3.10.0 # v3.10.2
    
    dependencies:
     flutter:
       sdk: flutter
    
     chopper: ^7.0.9
     envied: ^0.5.2
    
    dev_dependencies:
     flutter_test:
       sdk: flutter
    
     flutter_lints: ^3.0.1
    
     build_runner: ^2.4.6
     chopper_generator: ^7.0.6
     envied_generator: ^0.5.2
  2. create dummy .env file on project root.

    API_KEY=dummy4p1K3y
  3. create an obfuscate Env class.

    @Envied(obfuscate: true)
    abstract final class Env {
     @EnviedField(varName: 'API_KEY')
     static final String apiKey = _Env.apiKey; //it's final because there's a step to decrypt it.
    }
  4. fetch dependencies then generate env.

    flutter pub get
    dart run build_runner build -d
  5. try using the chopper API.

    mixin ClientHeaders on ChopperService {
     Map<String, String> get headers => {'x-api-key': Env.apiKey};
    }
    
    @ChopperApi(baseUrl: '/users')
    abstract class UsersService extends ChopperService with ClientHeaders {
     @Get(headers: headers) // WHY IMMUTABLE?
     Future<Response<String>> getUserByEmail() {}
    }

Expected results: No Error At All

Actual results: immutable for the [GET] annotation

Code sample ```dart import 'package:chopper/chopper.dart'; import 'package:envied/envied.dart'; import 'package:flutter/material.dart'; part 'main.chopper.dart'; part 'main.g.dart'; void main() { runApp(const MainApp()); } class MainApp extends StatelessWidget { const MainApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: Scaffold( body: Center( child: Text('Hello World!'), ), ), ); } } @Envied(obfuscate: true) abstract final class Env { @EnviedField(varName: 'API_KEY') static final String apiKey = _Env.apiKey; // it's final because there's a step to decrypt it. } mixin ClientHeaders on ChopperService { Map get headers => {'x-api-key': Env.apiKey}; } @ChopperApi(baseUrl: '/users') abstract class UsersService extends ChopperService with ClientHeaders { @Get(headers: headers) // WHY IMMUTABLE? Future> getUserByEmail() {} } ```
Logs ``` ``` ``` Analyzing chopper_headers_issue... error • lib\chopper_example.dart:13:17 • Arguments of a constant creation must be constant expressions. Try making the argument a valid constant, or use 'new' to call the constructor. • const_with_non_constant_argument error • lib\chopper_example.dart:14:28 • The body might complete normally, causing 'null' to be returned, but the return type, 'Future>', is a potentially non-nullable type. Try adding either a return or a throw statement at the end. • body_might_complete_normally error • lib\main.dart:39:17 • Arguments of a constant creation must be constant expressions. Try making the argument a valid constant, or use 'new' to call the constructor. • const_with_non_constant_argument error • lib\main.dart:40:28 • The body might complete normally, causing 'null' to be returned, but the return type, 'Future>', is a potentially non-nullable type. Try adding either a return or a throw statement at the end. • body_might_complete_normally info • lib\chopper_example.chopper.dart:10:13 • The declaration '_$UsersService' isn't referenced. Try removing the declaration of '_$UsersService'. • unused_element info • lib\main.chopper.dart:10:13 • The declaration '_$UsersService' isn't referenced. Try removing the declaration of '_$UsersService'. • unused_element 6 issues found. ``` ``` Flutter 3.10.2 • channel stable • https://github.com/flutter/flutter.git Framework • revision 9cd3d0d9ff (6 months ago) • 2023-05-23 20:57:28 -0700 Engine • revision 90fa3ae28f Tools • Dart 3.0.2 • DevTools 2.23.1 ```
KeidsID commented 11 months ago

I really like the chopper API after read the docs, but can't use it because of this.

techouse commented 11 months ago

If you want it dynamic simply use it like this

Future<Response<String>> getUserByEmail(
  @Header() String? name, // <-- like this
) {}

And please, don't use this approach to handle auth. Use the dedicated authenticator interceptor for that.