Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fixed for the issue (#125) #129

Merged
merged 3 commits into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Release Note

## v0.5.0

- The return type of `MastodonResponse<bool>` has been modified to assign an object corresponding to each endpoint. Basically, if there is no return value for a successful POST or DELETE method, an `Empty` object is returned as `data`. It means that the request was successful if `Empty` is returned; if the request failed, an exception is thrown. ([#125](https://github.com/mastodon-dart/mastodon-api/issues/125))
- Added `domain_blocks API methods`. ([#12](https://github.com/mastodon-dart/mastodon-api/issues/12))
- `GET /api/v1/domain_blocks`
- `POST /api/v1/domain_blocks`
Expand Down
1 change: 1 addition & 0 deletions lib/mastodon_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export 'package:mastodon_api/src/service/entities/conversation.dart';
export 'package:mastodon_api/src/service/entities/display_media_setting.dart';
export 'package:mastodon_api/src/service/entities/emoji.dart';
export 'package:mastodon_api/src/service/entities/emoji_reaction.dart';
export 'package:mastodon_api/src/service/entities/empty.dart';
export 'package:mastodon_api/src/service/entities/extended_description.dart';
export 'package:mastodon_api/src/service/entities/field.dart';
export 'package:mastodon_api/src/service/entities/instance.dart';
Expand Down
89 changes: 28 additions & 61 deletions lib/src/service/base_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import '../core/exception/rate_limit_exceeded_exception.dart';
import '../core/exception/unauthorized_exception.dart';
import '../core/service_helper.dart';
import '../core/util/json_utils.dart';
import 'entities/empty.dart';
import 'entities/rate_limit.dart';
import 'response/mastodon_response.dart';

Expand Down Expand Up @@ -66,9 +67,12 @@ abstract class _Service {
final UserContext userContext,
final String unencodedPath, {
List<MultipartFile> files = const [],
bool checkUnprocessableEntity = false,
});

MastodonResponse<Empty> transformEmptyResponse(
Response response,
);

MastodonResponse<D> transformSingleDataResponse<D>(
Response response, {
required DataBuilder<D> dataBuilder,
Expand All @@ -82,8 +86,6 @@ abstract class _Service {
MastodonResponse<List<D>> transformMultiRawDataResponse<D>(
Response response,
);

MastodonResponse<bool> evaluateResponse(final Response response);
}

abstract class BaseService implements _Service {
Expand Down Expand Up @@ -142,85 +144,76 @@ abstract class BaseService implements _Service {
final String unencodedPath, {
Map<String, dynamic> queryParameters = const {},
dynamic body = const {},
bool checkEntity = false,
}) async =>
await _helper.post(
userContext,
unencodedPath,
queryParameters: queryParameters,
body: body,
validate: ((response) => checkResponse(
response,
checkEntity,
)),
validate: checkResponse,
);

@override
Future<Response> delete(
UserContext userContext,
final String unencodedPath, {
dynamic body = const {},
bool checkUnprocessableEntity = false,
}) async =>
await _helper.delete(
userContext,
unencodedPath,
body: body,
validate: ((response) => checkResponse(
response,
checkUnprocessableEntity,
)),
validate: checkResponse,
);

@override
Future<Response> put(
UserContext userContext,
final String unencodedPath, {
dynamic body = const {},
bool checkUnprocessableEntity = false,
}) async =>
await _helper.put(
userContext,
unencodedPath,
body: body,
validate: ((response) => checkResponse(
response,
checkUnprocessableEntity,
)),
validate: checkResponse,
);

@override
Future<Response> patch(
UserContext userContext,
final String unencodedPath, {
dynamic body = const {},
bool checkUnprocessableEntity = false,
}) async =>
await _helper.patch(
userContext,
unencodedPath,
body: body,
validate: ((response) => checkResponse(
response,
checkUnprocessableEntity,
)),
validate: checkResponse,
);

@override
Future<Response> patchMultipart(
final UserContext userContext,
final String unencodedPath, {
List<MultipartFile> files = const [],
bool checkUnprocessableEntity = false,
}) async =>
await _helper.patchMultipart(
userContext,
unencodedPath,
files: files,
validate: ((response) => checkResponse(
response,
checkUnprocessableEntity,
)),
validate: checkResponse,
);

@override
MastodonResponse<Empty> transformEmptyResponse(
Response response,
) =>
MastodonResponse(
rateLimit: RateLimit.fromJson(
rateLimitConverter.convert(response.headers),
),
data: const Empty(),
);

@override
Expand Down Expand Up @@ -268,32 +261,8 @@ abstract class BaseService implements _Service {
);
}

@override
MastodonResponse<bool> evaluateResponse(final Response response) =>
MastodonResponse(
rateLimit: RateLimit.fromJson(
rateLimitConverter.convert(response.headers),
),
data: _evaluateResponse(response),
);

bool _evaluateResponse(final Response response) {
if (response.statusCode == 204) {
//! 204: No Content.
return true;
}

if (response.statusCode == 200) {
//! Okay, it's succeeded.
return true;
}

return false;
}

Response checkResponse(
final Response response,
final bool checkEntity,
) {
if (response.statusCode == 204) {
//! 204: No Content.
Expand All @@ -316,17 +285,15 @@ abstract class BaseService implements _Service {
throw RateLimitExceededException('Rate limit exceeded.', response);
}

if (checkEntity) {
if (400 <= response.statusCode && response.statusCode < 500) {
throw MastodonException(
'Required parameter is missing or improperly formatted.',
response,
);
}

tryJsonDecode(response, response.body);
if (400 <= response.statusCode && response.statusCode < 500) {
throw MastodonException(
'Required parameter is missing or improperly formatted.',
response,
);
}

tryJsonDecode(response, response.body);

return response;
}

Expand Down
11 changes: 11 additions & 0 deletions lib/src/service/entities/empty.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2023 Kato Shinya. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided the conditions.

class Empty {
/// Returns the new instance of [Empty].
const Empty();

@override
String toString() => '{}';
}
15 changes: 10 additions & 5 deletions lib/src/service/response/mastodon_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// modification, are permitted provided the conditions.

// 🌎 Project imports:
import '../entities/empty.dart';
import '../entities/rate_limit.dart';

/// The class represents the response from Mastodon API.
Expand All @@ -19,11 +20,15 @@ class MastodonResponse<D> {
/// The data field
final D data;

Map<String, dynamic> toJson() => {
'data': data is List
? (data as List).map((e) => e.toJson()).toList()
: (data as dynamic).toJson(),
};
Map<String, dynamic> toJson() => data is Empty
? {
'data': {},
}
: {
'data': data is List
? (data as List).map((e) => e.toJson()).toList()
: (data as dynamic).toJson(),
};

@override
String toString() {
Expand Down
Loading