{"id":26092908,"url":"https://github.com/jazzshu/financeapp","last_synced_at":"2026-04-11T07:04:41.091Z","repository":{"id":143113460,"uuid":"602729054","full_name":"jazzshu/FinanceApp","owner":"jazzshu","description":"Budgeting App using Neo4j","archived":false,"fork":false,"pushed_at":"2023-03-28T19:55:33.000Z","size":116,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-24T09:32:10.341Z","etag":null,"topics":["docker","graphdb","jenkins","jwt","mapstruct","neo4j","spring-boot","spring-security","swagger"],"latest_commit_sha":null,"homepage":"","language":"Java","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/jazzshu.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-16T20:25:16.000Z","updated_at":"2023-03-03T11:19:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"95804383-0752-4380-83e1-5f9ef2463d6f","html_url":"https://github.com/jazzshu/FinanceApp","commit_stats":null,"previous_names":["jazzshu/financeapp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzshu%2FFinanceApp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzshu%2FFinanceApp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzshu%2FFinanceApp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzshu%2FFinanceApp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jazzshu","download_url":"https://codeload.github.com/jazzshu/FinanceApp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242679511,"owners_count":20168163,"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":["docker","graphdb","jenkins","jwt","mapstruct","neo4j","spring-boot","spring-security","swagger"],"created_at":"2025-03-09T11:10:28.574Z","updated_at":"2026-04-11T07:04:36.071Z","avatar_url":"https://github.com/jazzshu.png","language":"Java","readme":"# Budget-Finance App\n\nThis application serves as a basic example on how to use a Graph type DB in a CRUD REST API.\n\nI created this project to use and implement some new technologies I came across, so that this repository would also\nserve as a reminder for future projects on how to use this technologies. Please feel free to use or interact with this\nrepository as you wish.\n\n#### Tech Stack\n\nThe tech stack used for this project is as follows:\n- [Java 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)\n- [Spring 3.0.2](https://spring.io/quickstart)\n- [Spring Security](https://docs.spring.io/spring-security/reference/index.html) \n- [JWT](https://jwt.io/)\n- [MapStruct](https://mapstruct.org/)\n- [Neo4j](https://neo4j.com/)\n- [Swagger](https://swagger.io/)\n- [Docker](https://www.docker.com/)\n- [Jenkins](https://www.jenkins.io/)\n\nIn order to use Neo4j as the GraphDB, java 17 is required.\n\n### Implementation\n\n#### Spring Security\nFirst off the Spring Security side needs to be implemented. As you can see, I created a User entity\nthat implements UserDetails from Spring Security. This is needed as we are going to retrieve from the UserRepository\nthe user based of the email with which he/she registers to our backend.\n\nIn this way, the user can then obtain a JWT token signed with his credentials and an expiration date that\nSpring will check everytime before making a REST call. \n\nAll the configuration is basically boilerplate code and it follows best practices in terms of security.\nThe only endpoints I whitelisted from Spring Security are the \"/auth\" and \"/swagger-ui/**\" endpoints.\n\nYou can find this code under the ***config*** package. \n\nAfter the Spring Security is created, and we can successfully retrieve a token, we then proceed in creating\nthe other API's. \n\n#### Neo4j\nWe followed the MVC model and created first the Repositories, then the Services and finally the Controllers.\nAs you can see the Entities need to be annotated with ***@Node*** and no @GeneratedValue needs to be included, as\nwe are going to manually set id's for our Neo4j nodes, as the official documentation recommends.\n\nWe then define a **@Relationship** towards the entity we want to tie with. For instance the User entity has a \nrelationship called *OWNS* towards the Budget entity.\n\nTo define custom queries we need to use Cypher Query language, as you can see in *BudgetRepository*.\n\nRemember to define your application as a *@EnableNeo4jRepositories* in your main class.\n\n#### MapStruct\nWhen passing data to and from your backend it is important that you hide useless information from the outside world,\nthat is why you need to use DTO's when transferring data. To do so I used this library I came across,\nnamed MapStruct. \n\nTo import MapStruct in your project, add this dependency to your pom.xml:\n```\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.mapstruct\u003c/groupId\u003e\n  \u003cartifactId\u003emapstruct\u003c/artifactId\u003e\n  \u003cversion\u003e1.5.3.Final\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.mapstruct\u003c/groupId\u003e\n  \u003cartifactId\u003emapstruct-processor\u003c/artifactId\u003e\n  \u003cversion\u003e1.5.3.Final\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nAll you have to do is define an interface and annotate it with ***@Mapper(componentModel = \"spring\")***.\nIt is important to use the componentModel attribute, because we need to compile the project so that MapStruct\nwill create the mapper classes that will map from an object to another. In this case, take for instance the UserMapper\ninterface, we are mapping from a User entity to a UserResponse entity, and from a UserRequest entity to a User entity.\n\nRemember to always **mvn clean install** when creating or modifying one of these interfaces. \n\nRemember also that as MapStruct uses Lombok annotations if you are using Lombok, that you need to include the mapstruct plugin after your lombok one on the pom.xml file.\n\n#### Swagger\nWe used Swagger 3 for this project, and to do so you need to create a SwaggerConfig file and basically copy the\nboilerplate code there is. \nGiven that we are using Spring Security for every API you need to tell Swagger that this API's are authorized through\nJWT, and once done so you will see an \"Authorize\" button appear in Swagger-UI where you will need to input a \nvalid JWT token in order to use your endpoints.\n\nYou also need to define ***@SecurityScheme(name = SWAGGER_AUTHORIZATION, scheme = \"bearer\", type = SecuritySchemeType.HTTP, in = SecuritySchemeIn.HEADER)***\nin your main class and then for every Controller class you need to add ***@SecurityRequirement(name = SWAGGER_AUTHORIZATION)***.\n(SWAGGER_AUTHORIZATION is a String you can choose but that you need to use across the controllers you want to be authorized).\n\n#### Docker\nTo develop this project I used docker-compose.\nYou can see the docker-compose.yml file at the root of the project. I basically have 2 services, one is the \napp itself, that we are building from the Dockerfile and connect to it through port 8080.\nAs you can see the pass also some environment variables such as uri and password. \nThe uri you need to use when running on Docker is \"bolt://host.docker.internal:7687\" while you can simply use\n\"bolt://localhost:7689\" when running as a normal Spring app.\n\nI then pull the neo4j image from Docker Hub, give it the default ports and pass in the NEO4J_AUTH environment\nvariables which correspond to username/password.\n\nBoth of these services need to run on the same network, in my case the **budget-network**.\n\n#### Jenkins\nWe created a basic Jenkinsfile to build and deploy the docker image to ECR on AWS. \nGiven that you cannot deploy a docker-compose stack, I simply pull the neo4j image on my AWS Linux machine\nand than built and deployed the App file as a Java jar, uploaded it to ECR and then pulled it on the same machine.\nRemember to pass in the environmental variables when running the **docker run** command.\n\n### Author\nJason Shuyinta\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazzshu%2Ffinanceapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjazzshu%2Ffinanceapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazzshu%2Ffinanceapp/lists"}