405 means that you don't have a route that supports the method used.
Check what flutter sends and make sure it matches what you have in your routes file.
hello i have this 405 error while creating a ticket from my flutter mobile app (i am linking laravel 5.6 with flutter) but when i test the endpoint in postman it works the error only happens when i try creating in flutter this is the routes/api:
Route::middleware('auth:api')->group(function () {
Route::get('tickets', [TicketController::class, 'index']);
Route::get('tickets/create', [TicketController::class, 'create']);
Route::post('tickets', [TicketController::class, 'store']);
Route::get('tickets/{ticket}', [TicketController::class, 'show']);
Route::get('tickets/{ticket}/edit', [TicketController::class, 'edit']);
Route::put('tickets/{ticket}', [TicketController::class, 'update']);
Route::delete('tickets/{ticket}', [TicketController::class, 'destroy']);
Route::put('tickets/{ticket}/validate', [TicketController::class, 'validateTicket']); });
note that when i get the tickets list it works i am using this
/// Route::post('tickets', [TicketController::class, 'store']);
and i am calling it using dio.post, the baseurl is my domain/api/tickets, note that in the postman they all work
405 means that you don't have a route that supports the method used.
Check what flutter sends and make sure it matches what you have in your routes file.
@Tray2 this is the flutter code :
// code api avec dio package pour createTickets
Future<void> createComplaint({
required String address,
required String description,
required String status,
required String priority,
required String category,
File? image,
required String token,
}) async {
try {
FormData createFormData() {
return FormData.fromMap({
'address': address,
'description': description,
'status': status,
'priority': priority,
'category': category,
if (image != null)
'attachment': MultipartFile.fromFileSync(image.path),
});
}
print('Sending request to $baseUrl with token: $token');
Response response = await _dio.post(
baseUrl, // Ensure this URL is correct and expects a POST request
data: createFormData(),
options: Options(
headers: {
'Authorization': 'Bearer $token',
},
validateStatus: (status) {
return status! < 500; // Accept all status codes below 500
},
),
);
// Handle 302 redirection
if (response.statusCode == 302) {
String? redirectUrl = response.headers['location']?.first;
if (redirectUrl != null) {
print('Following redirection to: $redirectUrl');
response = await _dio.post(
redirectUrl,
data: createFormData(),
options: Options(
headers: {
'Authorization': 'Bearer $token',
},
validateStatus: (status) {
return status! < 500;
},
),
);
}
}
print('Response status code: ${response.statusCode}');
print('Response data: ${response.data}');
print('Response headers: ${response.headers}');
if (response.statusCode != 200 && response.statusCode != 201) {
throw Exception('Failed to create complaint. Status code: ${response.statusCode}');
}
} catch (e) {
print('Error creating complaint: $e');
rethrow;
}
}
//code de controller:
Future<void> addComplaint(Complaint complaint) async {
String? token = gsService.getToken();
const String createComplaintUrl = 'domain/api/tickets';
if (token != null) {
try {
await apiService.createComplaint(
address: complaint.address,
description: complaint.description,
status: complaint.status,
priority: complaint.priority,
category: complaint.category,
image: complaint.attachmentUrl != null ? File(complaint.attachmentUrl!) : null,
token: token,
);
complaints.add(complaint);
Get.snackbar("Success", "Complaint created successfully");
} catch (e) {
Get.snackbar("Error", "Failed to create complaint: ${e.toString()}");
logger.e("Error creating complaint: $e");
}
} else {
Get.snackbar("Error", "Token not found");
logger.e("Error: Token not found");
}
}
we are using post and we doubled checked the url , the problem is that when we test using postman it works but in the flutter app it gives 405 how can we fix it
@namonaki What does you routes file look like?
//login+logout API Route::post('register', [AuthController::class, 'register']); Route::post('login', [AuthController::class, 'login']);
Route::middleware('auth:api')->group(function () { Route::post('logout', [AuthController::class, 'logout']); Route::get('user', function(Request $request) { return $request->user(); }); });
//user tickets Route::middleware('auth:api')->group(function () { Route::get('tickets', [TicketController::class, 'index']); Route::get('tickets/create', [TicketController::class, 'create']); Route::post('tickets', [TicketController::class, 'store']); Route::get('tickets/{ticket}', [TicketController::class, 'show']); Route::get('tickets/{ticket}/edit', [TicketController::class, 'edit']); Route::put('tickets/{ticket}', [TicketController::class, 'update']); Route::delete('tickets/{ticket}', [TicketController::class, 'destroy']); Route::put('tickets/{ticket}/validate', [TicketController::class, 'validateTicket']); });
@namonaki Place all code between three back ticks ´
//Code goes here
@Tray2 ''' /// //login+logout API Route /// post('register', [AuthController::class, 'register']); Route::post('login', [AuthController::class, 'login']); /// Route::middleware('auth:api')->group(function () { Route::post('logout', [AuthController::class, 'logout']); /// Route::get('user', function(Request $request) { return $request->user(); }); }); /// //user tickets /// Route::middleware('auth:api')->group(function () /// { Route::get('tickets', [TicketController::class, 'index']); /// Route::get('tickets/create', [TicketController::class, 'create']); /// Route::post('tickets', [TicketController::class, 'store']); /// Route::get('tickets/{ticket}', [TicketController::class, 'show']); /// Route::get('tickets/{ticket}/edit', [TicketController::class, 'edit']); /// Route::put('tickets/{ticket}', [TicketController::class, 'update']); /// Route::delete('tickets/{ticket}', [TicketController::class, 'destroy']); /// Route::put('tickets/{ticket}/validate', [TicketController::class, 'validateTicket']); }); /// '''
@namonaki back ticks ``` not single quotes '''
//login+logout API Route
/// post('register', [AuthController::class, 'register']);
///Route::post('login', [AuthController::class, 'login']);
/// Route::middleware('auth:api')->group(function () {
// Route::post('logout', [AuthController::class, 'logout']);
/// Route::get('user', function(Request $request) { return $request->user(); }); });
//user tickets
/// Route::middleware('auth:api')->group(function ()
/// { Route::get('tickets', [TicketController::class, 'index']);
/// Route::get('tickets/create', [TicketController::class, 'create']);
/// Route::post('tickets', [TicketController::class, 'store']);
/// Route::get('tickets/{ticket}', [TicketController::class, 'show']);
/// Route::get('tickets/{ticket}/edit', [TicketController::class, 'edit']);
/// Route::put('tickets/{ticket}', [TicketController::class, 'update']);
/// Route::delete('tickets/{ticket}', [TicketController::class, 'destroy']);
/// Route::put('tickets/{ticket}/validate', [TicketController::class, 'validateTicket']); }); ```
@namonaki So you have commented out all the routes?
@Tray2 no no this is just befor i used the ` back ticks just to seperate the routes my actual routes are :
//login+logout API
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);
Route::middleware('auth:api')->group(function () {
Route::post('logout', [AuthController::class, 'logout']);
Route::get('user', function(Request $request) {
return $request->user();
});
});
//user tickets
Route::middleware('auth:api')->group(function () {
Route::get('tickets', [TicketController::class, 'index']);
Route::get('tickets/create', [TicketController::class, 'create']);
Route::post('tickets', [TicketController::class, 'store']);
Route::get('tickets/{ticket}', [TicketController::class, 'show']);
Route::get('tickets/{ticket}/edit', [TicketController::class, 'edit']);
Route::put('tickets/{ticket}', [TicketController::class, 'update']);
Route::delete('tickets/{ticket}', [TicketController::class, 'destroy']);
Route::put('tickets/{ticket}/validate', [TicketController::class, 'validateTicket']);
});
i have a 405 error everytime i create a ticket
Route::post('tickets', [TicketController::class, 'store']);
the url i use in flutter is mydomain/api/tickets
and i am using dio.post
when i test the endpoint in postman no error
@namonaki Well then, press F12 in your browser and take a look at what it attempts to access, and compare that to your routes file. My guess is that you have a missing /, or one more than you need.
@Tray2 won't that also effect postman testing ?
@namonaki No, because with postman you know what method you use, and in flutter you don't, so you need to verify that flutter uses the correct method.
@namonaki Which route you're calling from your flutter routes? The post is failed to specify on which route you're getting 405? Seems like the method of the routes is different than declared in the route file.
For an example: Route::post('logout', [AuthController::class, 'logout']); /// This is post route but if you trigger it using the get request then it will throw 405 error. Please cross check the method with which you are encounterring the 405 eror.
@DhPandya i am using this :
Route::post('tickets', [TicketController::class, 'store']);
POST mydomain/api/tickets
// this is the flutter code and we are using dio.post
// code api avec dio package pour createTickets
Future<void> createComplaint({
required String address,
required String description,
required String status,
required String priority,
required String category,
File? image,
required String token,
}) async {
try {
FormData createFormData() {
return FormData.fromMap({
'address': address,
'description': description,
'status': status,
'priority': priority,
'category': category,
if (image != null)
'attachment': MultipartFile.fromFileSync(image.path),
});
}
print('Sending request to $baseUrl with token: $token');
Response response = await _dio.post(
baseUrl, // my domain/api/tickets
data: createFormData(),
options: Options(
headers: {
'Authorization': 'Bearer $token',
},
validateStatus: (status) {
return status! < 500; // Accept all status codes below 500
},
),
);
// Handle 302 redirection
if (response.statusCode == 302) {
String? redirectUrl = response.headers['location']?.first;
if (redirectUrl != null) {
print('Following redirection to: $redirectUrl');
response = await _dio.post(
redirectUrl,
data: createFormData(),
options: Options(
headers: {
'Authorization': 'Bearer $token',
},
validateStatus: (status) {
return status! < 500;
},
),
);
}
}
print('Response status code: ${response.statusCode}');
print('Response data: ${response.data}');
print('Response headers: ${response.headers}');
if (response.statusCode != 200 && response.statusCode != 201) {
throw Exception('Failed to create complaint. Status code: ${response.statusCode}');
}
} catch (e) {
print('Error creating complaint: $e');
rethrow;
}
}
the endpoint works in postman but in flutter is giving 405
As said by @DhPangya, you cannot send data to post route. You should call the route where your form is, fill the form and then call the store method.
Please or to participate in this conversation.