module account.api; import handy_httpd; import asdf; import profile.service; import account.model; import money.currency; struct AccountResponse { ulong id; string createdAt; bool archived; string type; string numberSuffix; string name; string currency; string description; static AccountResponse of(in Account account) { AccountResponse r; r.id = account.id; r.createdAt = account.createdAt.toISOExtString(); r.archived = account.archived; r.type = account.type.id; r.numberSuffix = account.numberSuffix; r.name = account.name; r.currency = account.currency.code.dup; r.description = account.description; return r; } } void handleGetAccounts(ref HttpRequestContext ctx) { import std.algorithm; auto ds = getProfileDataSource(ctx); auto accounts = ds.getAccountRepository().findAll() .map!(a => AccountResponse.of(a)); ctx.response.writeBodyString(serializeToJson(accounts), "application/json"); } void handleGetAccount(ref HttpRequestContext ctx) { ulong accountId = ctx.request.getPathParamAs!ulong("accountId"); auto ds = getProfileDataSource(ctx); auto account = ds.getAccountRepository().findById(accountId) .orElseThrow(() => new HttpStatusException(HttpStatus.NOT_FOUND)); ctx.response.writeBodyString(serializeToJson(AccountResponse.of(account)), "application/json"); } struct AccountCreationPayload { string type; string numberSuffix; string name; string currency; string description; } void handleCreateAccount(ref HttpRequestContext ctx) { auto ds = getProfileDataSource(ctx); AccountCreationPayload payload; try { payload = deserialize!(AccountCreationPayload)(ctx.request.readBodyAsString()); } catch (SerdeException e) { ctx.response.status = HttpStatus.BAD_REQUEST; ctx.response.writeBodyString("Invalid account payload."); return; } AccountType type = AccountType.fromId(payload.type); Currency currency = Currency.ofCode(payload.currency); Account account = ds.getAccountRepository().insert( type, payload.numberSuffix, payload.name, currency, payload.description ); ctx.response.writeBodyString(serializeToJson(AccountResponse.of(account)), "application/json"); } void handleDeleteAccount(ref HttpRequestContext ctx) { ulong accountId = ctx.request.getPathParamAs!ulong("accountId"); auto ds = getProfileDataSource(ctx); ds.getAccountRepository().deleteById(accountId); }