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

feat(#61): generate client for Serinus Applications #100

Merged
merged 17 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
feat(#61): add check on user-defined routes, improved performances
  • Loading branch information
francescovallone committed Oct 7, 2024
commit 444f6a91040d76bab7ba18d34f4e21de96e681d8
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*.ipr
*.iws
.idea/

*.DS_Store
# Conventional directory for build output.
build/

Expand Down
7 changes: 1 addition & 6 deletions packages/serinus/example/lib/app_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ class AppController extends Controller {
/// The constructor of the [AppController] class.
AppController({super.path = '/'}) {
on(HelloWorldRoute(), _handleEcho);
on(
HelloWorldRoute(),
(context) async {
return 'Hello, World!';
},
);
on(Route.get('/hello'), (context) async {
return 'Hello';
});
Expand All @@ -22,3 +16,4 @@ class AppController extends Controller {
return 'Echo';
}
}

4 changes: 1 addition & 3 deletions packages/serinus/example/lib/app_routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,5 @@ import 'package:serinus/serinus.dart';
/// The [HelloWorldRoute] class is used to create a route that returns 'Hello, World!'.
class HelloWorldRoute extends Route {
/// The constructor of the [HelloWorldRoute] class.
HelloWorldRoute() : super(path: '/param-<id>', method: HttpMethod.get, queryParameters: {
'id': String,
});
HelloWorldRoute({super.queryParameters}) : super(path: '/', method: HttpMethod.get);
}
2 changes: 1 addition & 1 deletion packages/serinus/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ environment:
sdk: '>=3.0.0 <4.0.0'

dependencies:
serinus: ^0.6.0
serinus: ^0.6.2
dart_mappable: ^4.2.2
freezed_annotation: ^2.4.4
json_annotation: ^4.9.0
Expand Down
4 changes: 3 additions & 1 deletion packages/serinus/lib/src/containers/module_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ final class ModulesContainer {
...providers.providers,
...providers.exportedProviders,
...injectables.providers,
...globalProviders
},
);
}
Expand Down Expand Up @@ -342,7 +343,8 @@ final class ModulesContainer {
providers: {
...providersInjectable,
...subModuleInjectables.providers,
...exportedProvidersInjectables
...exportedProvidersInjectables,
...globalProviders,
},
);
}
Expand Down
5 changes: 4 additions & 1 deletion packages/serinus/lib/src/containers/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,17 @@ class RouteData {
final bool isStatic;

/// The [RouteData] constructor is used to create a new instance of the [RouteData] class.
RouteData({
const RouteData({
required this.id,
required this.path,
required this.method,
required this.controller,
required this.routeCls,
required this.moduleToken,
required this.spec,
this.isStatic = false,
this.queryParameters = const {},
});

final RouteHandler spec;
}
2 changes: 1 addition & 1 deletion packages/serinus/lib/src/contexts/request_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class RequestContext extends BaseContext {

/// The [stream] method is used to stream data to the response.
StreamableResponse stream() {
return _streamable..init();
return _streamable;
}
}

Expand Down
10 changes: 2 additions & 8 deletions packages/serinus/lib/src/contexts/ws_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,13 @@ final class WebSocketContext extends BaseContext {
///
/// The [broadcast] parameter is used to broadcast the data to all clients.
void send(dynamic data) {
if (_serializer != null) {
data = _serializer?.serialize(data);
}
_wsAdapter.send(data, key: id);
_wsAdapter.send(_serializer?.serialize(data) ?? data, key: id);
}

/// This method is used to broadcast data to all clients.
///
/// The [data] parameter is the data to be sent.
void broadcast(dynamic data) {
if (_serializer != null) {
data = _serializer?.serialize(data);
}
_wsAdapter.send(data);
_wsAdapter.send(_serializer?.serialize(data) ?? data);
}
}
5 changes: 2 additions & 3 deletions packages/serinus/lib/src/core/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:collection/collection.dart';
import 'package:meta/meta.dart';
import 'package:uuid/v4.dart';

import '../containers/router.dart';
import '../contexts/contexts.dart';
import 'metadata.dart';
import 'parse_schema.dart';
Expand Down Expand Up @@ -38,8 +37,8 @@ abstract class Controller {
Map<String, RouteHandler> get routes => UnmodifiableMapView(_routes);

/// The [get] method is used to get a route.
RouteHandler? get(RouteData routeData) {
return _routes[routeData.id];
RouteHandler? get(String routeId) {
return _routes[routeId];
}

/// The [metadata] property contains the metadata of the controller.
Expand Down
2 changes: 1 addition & 1 deletion packages/serinus/lib/src/extensions/object_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension JsonParsing on Object {

/// This method is used to check if the object can be converted to a json.
bool canBeJson() {
if (this is Uint8List) {
if (this is Uint8List || isPrimitive()) {
return false;
}
return this is Map ||
Expand Down
6 changes: 1 addition & 5 deletions packages/serinus/lib/src/handlers/request_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,8 @@ class RequestHandler extends Handler {
}
final injectables =
modulesContainer.getModuleInjectablesByToken(routeData.moduleToken);
final routeSpec = routeData.spec;
final controller = routeData.controller;
final routeSpec = controller.get(routeData);
if (routeSpec == null) {
throw InternalServerErrorException(
message: 'Route spec not found for route ${routeData.path}');
}
final route = routeSpec.route;
final handler = routeSpec.handler;
final schema = routeSpec.schema;
Expand Down
3 changes: 3 additions & 0 deletions packages/serinus/lib/src/http/internal_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class InternalResponse {

/// This method is used to set the status code of the response.
void status(int statusCode) {
if(statusCode == _original.statusCode) {
return;
}
_original.statusCode = statusCode;
}

Expand Down
3 changes: 3 additions & 0 deletions packages/serinus/lib/src/http/streamable_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class StreamableResponse {

/// This method is used to send data to the response.
void send(Object data) {
if(!_initialized) {
init();
}
_response.write(data.toString());
}

Expand Down
4 changes: 3 additions & 1 deletion packages/serinus/lib/src/injector/explorer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ final class Explorer {
? module.runtimeType.toString()
: module.token,
isStatic: spec.handler is! Function,
queryParameters: spec.route.queryParameters),
queryParameters: spec.route.queryParameters,
spec: spec,
)
);
logger.info('Mapped {$routePath, $routeMethod} route');
}
Expand Down
24 changes: 21 additions & 3 deletions packages/serinus/test/containers/router_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ void main() async {
method: HttpMethod.get,
controller: TestController(),
routeCls: Type,
moduleToken: 'moduleToken');
moduleToken: 'moduleToken',
spec: (
body: null,
schema: null,
handler: 'hi',
route: Route.get('/test'),
));
router.registerRoute(routeData);
});

Expand All @@ -47,7 +53,13 @@ void main() async {
method: HttpMethod.get,
controller: TestController(),
routeCls: Type,
moduleToken: 'moduleToken');
moduleToken: 'moduleToken',
spec: (
body: null,
schema: null,
handler: 'hi',
route: Route.get('/test'),
));
router.registerRoute(routeData);
final result = router.getRouteByPathAndMethod('/test', HttpMethod.get);
expect(result.route, routeData);
Expand All @@ -64,7 +76,13 @@ void main() async {
method: HttpMethod.get,
controller: TestController(),
routeCls: Type,
moduleToken: 'moduleToken');
moduleToken: 'moduleToken',
spec: (
body: null,
schema: null,
handler: 'hi',
route: Route.get('/test'),
));
router.registerRoute(routeData);
final result = router.getRouteByPathAndMethod('/test', HttpMethod.post);
expect(result.route, isNull);
Expand Down
30 changes: 6 additions & 24 deletions packages/serinus/test/core/controller_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:serinus/serinus.dart';
import 'package:serinus/src/containers/router.dart';
import 'package:test/test.dart';

class TestController extends Controller {
Expand Down Expand Up @@ -38,30 +37,18 @@ void main() async {
});

test(
'when two routes with the same type and path are added to a controller, then it should throw an error',
'when two routes with the same type and different path are added to a controller, then it should register both routes',
() {
final controller = LeadingSlashController();
final route = GetRoute(path: '/test');
final route2 = GetRoute(path: '/');
controller.on(route, (context) async => 'ok!');
controller.on(route2, (context) async => 'ok!');
expect(
controller.get(RouteData(
id: controller.routes.keys.elementAt(0),
path: '/leading/test',
controller: controller,
method: HttpMethod.get,
moduleToken: '',
routeCls: GetRoute)),
controller.get(controller.routes.keys.elementAt(0)),
isA<RouteHandler>());
expect(
controller.get(RouteData(
id: controller.routes.keys.elementAt(1),
path: '/leading/',
controller: controller,
method: HttpMethod.get,
moduleToken: '',
routeCls: GetRoute)),
controller.get(controller.routes.keys.elementAt(1)),
isA<RouteHandler>());
});

Expand All @@ -72,14 +59,9 @@ void main() async {
final route = GetRoute(path: '/test');
controller.onStatic(route, 'ok!');
expect(
controller.get(RouteData(
id: controller.routes.keys.elementAt(0),
path: '/leading/test',
controller: controller,
method: HttpMethod.get,
moduleToken: '',
isStatic: true,
routeCls: GetRoute)),
controller.get(
controller.routes.keys.elementAt(0)
),
isA<RouteHandler>());
});

Expand Down
8 changes: 7 additions & 1 deletion packages/serinus/test/http/responses_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,13 @@ void main() async {
method: HttpMethod.get,
controller: controller,
routeCls: TestRoute,
moduleToken: 'TestModule'));
moduleToken: 'TestModule',
spec: (
body: null,
schema: null,
handler: 'hi',
route: TestRoute(path: 'path-error'),
)));
final request = await HttpClient()
.getUrl(Uri.parse('http://localhost:3000/path-error'));
final response = await request.close();
Expand Down
Loading
Loading