{"id":21023220,"url":"https://github.com/simerplaha/akka-typed-eventsourcing","last_synced_at":"2025-03-13T18:14:33.128Z","repository":{"id":92841202,"uuid":"46200639","full_name":"simerplaha/akka-typed-eventsourcing","owner":"simerplaha","description":"An implementation of Eventsourcing with Akka-typed, Spray, Slick \u0026 Postgres.","archived":false,"fork":false,"pushed_at":"2016-02-19T13:08:36.000Z","size":39,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-20T13:34:39.086Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://simerplaha.github.io/akka-typed-eventsourcing/","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simerplaha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-15T02:15:12.000Z","updated_at":"2020-04-09T02:05:12.000Z","dependencies_parsed_at":"2023-05-04T23:37:07.937Z","dependency_job_id":null,"html_url":"https://github.com/simerplaha/akka-typed-eventsourcing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simerplaha%2Fakka-typed-eventsourcing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simerplaha%2Fakka-typed-eventsourcing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simerplaha%2Fakka-typed-eventsourcing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simerplaha%2Fakka-typed-eventsourcing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simerplaha","download_url":"https://codeload.github.com/simerplaha/akka-typed-eventsourcing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243456567,"owners_count":20293904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T11:17:16.494Z","updated_at":"2025-03-13T18:14:33.081Z","avatar_url":"https://github.com/simerplaha.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Akka-typed-eventsourcing\n----\n\nAn implementation of Eventsourcing with Akka-typed, Spray, Slick \u0026 Postgres.\n\n## Summary\n----\n\n1. A simple Spray REST API to submit commands to Akka-typed's ActorSystem.\n2. Implements \"Actor per request\" pattern using typed actors.\n3. Provides base implementations for [AggregateManager](https://github.com/simerplaha/akka-typed-eventsourcing/blob/master/src/main/scala/aggregate/base/AggregateManager.scala) and [Aggregate](https://github.com/simerplaha/akka-typed-eventsourcing/blob/master/src/main/scala/aggregate/base/Aggregate.scala).\n4. Uses Akka-typed's Total behavior's lifecycle event 'PreStart' to replay all stored events which restores Actor's state.\n5. Implements an example of CQRS's read side using Akka's EventBus (Check [UserListener](https://github.com/simerplaha/akka-typed-eventsourcing/blob/master/src/main/scala/read/UserListener.scala)).\n5. Maps stored JSON events to relevant Case classes.\n6. Uses Slick-pg extension.\n7. Uses Gson for JSON parsing.\n\n## Running \n---\n\n1. Add your postgres database configuration in application.conf\n2. Run Schema.scala's main method to create the database schema\n3. Run Boot.scala to start application.\n\n## EVENTS table\n\nPERSISTENT_ID  |   EVENT_JSON  | EVENT_NAME | TAGS | CREATE_TIME\n-------------- | ------------- | ---------- | ---- | -----------\nString         |    String     |   String   | List[String] | Timestamp\n\n\n## APIs\n---\n\n#### Command: CreateUser\n##### Event - UserCreated\n\nhttp://localhost:8080/createUser?username=John\u0026name=Smith\u0026password=123\n\n    {\n        \"username\": \"John\",\n        \"name\": \"Smith\",\n        \"password\": \"123\",\n        \"deleted\": false\n    }\n\nRunning the same URL again returns error message\n    \n    {\n        \"message\": \"Username 'John' with name 'Smith' already exists.\"\n    }\n\n#### Command: UpdateName\n##### Event - UserNameUpdated\n\nhttp://localhost:8080/updateName?username=John\u0026name=Jhonny\n\n    {\n        \"username\": \"John\",\n        \"name\": \"Jhonny\",\n        \"password\": \"123\",\n        \"deleted\": false\n    }\n    \nRunning the same URL again returns error message\n\n    {\n        \"message\": \"Name unchanged!\",\n        \"state\": {\n            \"username\": \"John\",\n            \"name\": \"Jhonny\",\n            \"password\": \"123\",\n            \"deleted\": false\n        }\n    }\n    \n#### Command: ChangePassword\n##### Event - UserPasswordChanged\n\nhttp://localhost:8080/changePassword?username=John\u0026password=PA$$W0RD\n\n    {\n        \"username\": \"John\",\n        \"name\": \"Jhonny\",\n        \"password\": \"PA$$W0RD\",\n        \"deleted\": false\n    }\n\n#### Command: DeleteUser\n##### Event - UserDeleted\n\nhttp://localhost:8080/deleteUser?username=John\n\n    {\n        \"username\": \"John\",\n        \"name\": \"Jhonny\",\n        \"password\": \"PA$$W0RD\",\n        \"deleted\": true\n    }\n\nCalling CreateUser on a delete users display this message: http://localhost:8080/createUser?username=John\u0026name=Smith\u0026password=123\n\n    {\n        \"message\": \"Not a valid request: 'Initialize' for current state: 'deleted'\",\n        \"state\": {\n            \"username\": \"John\",\n            \"name\": \"Jhonny\",\n            \"password\": \"PA$$W0RD\",\n            \"deleted\": true\n        }\n    }\n    \n### TODOs\n- Test cases\n- Stopping Actors after reaching certain threshold of in-memory Actors.\n- Snapshotting\n- Use Kafka as eventstore instead.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimerplaha%2Fakka-typed-eventsourcing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimerplaha%2Fakka-typed-eventsourcing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimerplaha%2Fakka-typed-eventsourcing/lists"}