dart user service, dependency injection with riverpod

This commit is contained in:
2025-01-01 12:05:39 +00:00
parent cf3c34fb2f
commit bdd4042cef
22 changed files with 502 additions and 115 deletions
@@ -1,19 +0,0 @@
import 'package:backend_dart/domain/entities/user.dart';
import 'package:backend_dart/domain/repositories/user_repository.dart';
class RegisterUserUseCase {
final UserRepository userRepository;
RegisterUserUseCase(this.userRepository);
Future<void> execute(String name, String email, String password) async {
final user = User(
id: 'generated-id', // Eine Methode zur ID-Erzeugung einfügen
name: name,
email: email,
password: password, // In der Realität: Passwörter hashen
);
await userRepository.create(user);
}
}
@@ -0,0 +1,27 @@
import 'package:backend_dart/infrastructure/persistence/database.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
part 'user_service.g.dart'; // generated with 'pub run build_runner build'
class UserService {
final Database database;
UserService(this.database);
@Route.get('/')
Future<Response> listUsers(Request request) async {
return Response.ok('["user1"]');
}
@Route.get('/<userId>')
Future<Response> fetchUser(Request request, String userId) async {
final result = await database.users.findById(userId);
if (result != null) {
return Response.ok(result);
}
return Response.notFound('no such user');
}
// Create router using the generate function defined in 'userservice.g.dart'.
Router get router => _$UserServiceRouter(this);
}
@@ -0,0 +1,22 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user_service.dart';
// **************************************************************************
// ShelfRouterGenerator
// **************************************************************************
Router _$UserServiceRouter(UserService service) {
final router = Router();
router.add(
'GET',
r'/',
service.listUsers,
);
router.add(
'GET',
r'/<userId>',
service.fetchUser,
);
return router;
}
@@ -0,0 +1,8 @@
import 'package:backend_dart/application/user_service/user_service.dart';
import 'package:backend_dart/infrastructure/persistence/database_provider.dart';
import 'package:riverpod/riverpod.dart';
final userServiceProvider = Provider<UserService>((ref) {
final database = ref.read(databaseProvider);
return UserService(database);
});
-3
View File
@@ -1,3 +0,0 @@
int calculate() {
return 6 * 7;
}
+1 -1
View File
@@ -2,7 +2,7 @@ class User {
final String id;
final String name;
final String email;
final String password;
final String? password;
User({
required this.id,
@@ -0,0 +1,13 @@
import 'package:backend_dart/infrastructure/persistence/db/client.dart';
import 'package:backend_dart/infrastructure/persistence/prisma_user_repository.dart';
class Database {
final prisma = PrismaClient();
late final PrismaUserRepository users;
Database() {
users = PrismaUserRepository(prisma);
print('Database initialized');
}
}
@@ -0,0 +1,8 @@
import 'package:backend_dart/infrastructure/persistence/database.dart';
import 'package:riverpod/riverpod.dart';
final databaseProvider = Provider<Database>((ref) {
// Hier die Datenbankverbindung initialisieren
final database = Database();
return database;
});
@@ -1,60 +0,0 @@
import 'package:backend_dart/domain/entities/user.dart';
import 'package:backend_dart/domain/repositories/user_repository.dart';
import 'package:postgres/postgres.dart';
class PostgresUserRepository implements UserRepository {
final PostgreSQLConnection connection;
PostgresUserRepository(this.connection);
@override
Future<void> create(User user) async {
await connection.query(
'INSERT INTO users (id, name, email, password) VALUES (@id, @name, @mail, @pwd)',
substitutionValues: {
'id': user.id,
'name': user.name,
'mail': user.email,
'pwd': user.password,
},
);
}
@override
Future<User?> findByEmail(String email) async {
final results = await connection.query(
'SELECT id, name, email, password FROM users WHERE email = @mail',
substitutionValues: {'mail': email},
);
if (results.isNotEmpty) {
final row = results.first;
return User(
id: row[0],
name: row[1],
email: row[2],
password: row[3],
);
}
return null;
}
@override
Future<User?> findById(String id) async {
final results = await connection.query(
'SELECT id, name, email, password FROM users WHERE id = @id',
substitutionValues: {'id': id},
);
if (results.isNotEmpty) {
final row = results.first;
return User(
id: row[0],
name: row[1],
email: row[2],
password: row[3],
);
}
return null;
}
}
@@ -0,0 +1,57 @@
import 'package:backend_dart/domain/entities/user.dart';
import 'package:backend_dart/domain/repositories/user_repository.dart';
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
import 'package:orm/orm.dart';
import 'db/client.dart';
class PrismaUserRepository implements UserRepository {
final PrismaClient prisma;
PrismaUserRepository(this.prisma);
@override
Future<void> create(User user) async {
if (user.password == null) {
throw Exception('Password is required');
}
prisma.user.create(
data: PrismaUnion.$1(UserCreateInput(
id: user.id,
name: user.name,
email: user.email,
password: user.password!,
)));
}
@override
Future<User?> findByEmail(String email) async {
final user =
await prisma.user.findUnique(where: UserWhereUniqueInput(email: email));
if (user == null) {
return null;
}
return User(
id: user.id!,
name: user.name!,
email: user.email!,
password: user.password,
);
}
@override
Future<User?> findById(String id) async {
final user =
await prisma.user.findUnique(where: UserWhereUniqueInput(id: id));
if (user == null) {
return null;
}
return User(
id: user.id!,
name: user.name!,
email: user.email!,
password: user.password,
);
}
}
@@ -0,0 +1,25 @@
import 'package:backend_dart/application/user_service/user_service_provider.dart';
import 'package:riverpod/riverpod.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
Router getRouter(ProviderContainer container) {
final router = Router();
// Welcome and health routes
router.get('/', (Request request) {
return Response.ok('Welcome to ActaTempus!');
});
router.get('/health', (Request request) {
return Response.ok('Server is running');
});
// UserService instanzieren
final userService = container.read(userServiceProvider);
// UserService-Router an Haupt-Router binden
router.mount('/users/', userService.router.call);
return router;
}
+24 -9
View File
@@ -1,21 +1,36 @@
import 'dart:io';
import 'package:riverpod/riverpod.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:backend_dart/infrastructure/config/config.dart';
import 'router.dart';
class Server {
final Config config;
Server(this.config);
Future<void> start() async {
final server =
await HttpServer.bind(InternetAddress.anyIPv4, int.parse(config.port));
print('Listening on port ${config.port}');
Future<HttpServer> start() async {
final container = ProviderContainer();
// Load the router from the router file
final router = getRouter(container);
await for (HttpRequest request in server) {
request.response
..write('Welcome to ActaTempus!')
..close();
}
// Define the pipeline and attach the router
final handler = Pipeline()
.addMiddleware(logRequests()) // Logs all incoming requests
.addHandler(router.call);
// Start the server
final server = await shelf_io.serve(
handler,
InternetAddress.anyIPv4,
int.parse(config.port),
);
print('Server listening on port ${server.port}');
return server;
}
}