{"id":20846760,"url":"https://github.com/kimgoetzke/practice-recipes-db","last_synced_at":"2026-04-07T21:31:19.589Z","repository":{"id":158016393,"uuid":"596494691","full_name":"kimgoetzke/practice-recipes-db","owner":"kimgoetzke","description":"A containerised, multi-user web service created to practice using PostgreSQL, the Spring framework (Security, Crypto, Data), and Docker Compose.","archived":false,"fork":false,"pushed_at":"2023-02-07T06:25:40.000Z","size":88,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-27T06:47:55.885Z","etag":null,"topics":["api","docker-compose","java","junit5","openapi","postgresql","spring","swagger2"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kimgoetzke.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-02T10:00:27.000Z","updated_at":"2023-05-20T19:16:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"543c85e1-f209-4ea0-a144-6683ba4caa0c","html_url":"https://github.com/kimgoetzke/practice-recipes-db","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kimgoetzke/practice-recipes-db","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimgoetzke%2Fpractice-recipes-db","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimgoetzke%2Fpractice-recipes-db/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimgoetzke%2Fpractice-recipes-db/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimgoetzke%2Fpractice-recipes-db/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kimgoetzke","download_url":"https://codeload.github.com/kimgoetzke/practice-recipes-db/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimgoetzke%2Fpractice-recipes-db/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31530641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["api","docker-compose","java","junit5","openapi","postgresql","spring","swagger2"],"created_at":"2024-11-18T02:17:52.636Z","updated_at":"2026-04-07T21:31:19.563Z","avatar_url":"https://github.com/kimgoetzke.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# The Recipes Project\n\nThis repo contains a simple multi-users web service, written in Java and using the Spring framework. \n\nThis app was initially created as a [graduate project](https://hyperskill.org/projects/180) for the '[Spring Security for Java Backend Developer](https://hyperskill.org/tracks/38)' track on Hyperskill (JetBrains Academy). However, after finishing the project, I decided to:\n+ Add unit tests, resulting in \u003cins\u003e96% code coverage\u003c/ins\u003e\n+ Add an OpenAPI YAML spec for the API\n+ Migrate from using an H2 database to Postgres\n+ Containerise the app/db with Docker Compose\n+ Upgrade to the latest Spring Framework 6 (which required:)\n+ Refactoring/upgrading the security configuration to use SecurityFilterChain\n\nThe project is a simple multi-users web service for storing recipes. Some key features include:\n+ An API with a Spring Boot REST controller offering endpoints for creating users and adding/requesting/updating/deleting recipes\n+ Sprint Crypto to implement BCrypt encoding for passwords\n+ Sprint Security to allow only authorised users access (except for user registration)\n+ Processing and returning data in JSON format\n+ Using Project Lombok to reduce boilerplate code\n+ Docker Compose to separate app from database\n+ PostgreSQL database\n\n\n## Configuration \u0026 available endpoints\n\n+ Create JAR by running `gradle clean build -x test`\n+ Copy newly created JAR to src/main/docker with `cp build/libs/Recipes-DB-0.0.1-SNAPSHOT.jar src/main/docker`\n+ Run `docker compose up` to create and run images and containers\n+ Use local port `8881` for API requests\n\n### Register user\nPOST `api/register`\n+ Expects JSON with `email` (valid email) and `password` (8 character minimum)\n+ Example:\n  `{\n  \"email\": \"test@email.com\",\n  \"password\": \"password\"\n  }`\n+ Returns HTTP status code (`200` or `400`) based on success\n\n### Create recipe\nPOST `api/recipe/new`\n+ Expects JSON with `name`, `category`, `description`, `ingredients` (1+), `directions` (1+) and authorisation\n+ Example:\n  ```\n  {\n     \"name\": \"Fresh Mint Tea\",\n     \"category\": \"Beverage\",\n     \"description\": \"Light, aromatic and refreshing beverage, ...\",\n     \"ingredients\": [\"boiled water\", \"honey\", \"fresh mint leaves\"],\n     \"directions\": [\"Boil water\", \"Pour boiling hot water into a mug\", \"Add fresh mint leaves\", \"Mix and let the mint leaves seep for 3-5 minutes\", \"Add honey and mix again\"]\n  }\n  ```\n+ If successful, returns JSON with the generated `id` and HTTP status `200`, or `400`/`401` if invalid/unauthorised\n\n### Update recipe\nPUT `api/recipe/{id}`\n+ Expects JSON with `name`, `category`, `description`, `ingredients` (1+), `directions` (1+) and authorisation\n+ Example:\n  ```\n  {\n     \"name\": \"Even Fresher Mint Tea\",\n     \"category\": \"Beverage\",\n     \"description\": \"Light, aromatic and refreshing beverage, ...\",\n     \"ingredients\": [\"boiled water\", \"honey\", \"very fresh mint leaves\"],\n     \"directions\": [\"Boil water\", \"Pour boiling hot water into a mug\", \"Add very fresh mint leaves\", \"Mix and let the mint leaves seep for 3-5 minutes\", \"Add honey and mix again\"]\n  }\n  ```\n+ Returns HTTP status `204` if successful - or `403`/`404` if not the owner/recipe not found\n\n### Get recipe\nGET `api/recipe/{id}`\n+ Expects authorisation, no body required\n+ Returns JSON with `name`, `category`, `description`, `ingredients`, `directions`  and HTTP status `200` if successful, or `401`/`404` if unauthorised/not found\n\n### Search recipes\nGET `api/recipes/search`\n+ Expects authorisation, no body required\n+ Accepts either `?name=` (string containing) or `?category=`\n+ Returns sorted JSON with all recipes matching the search criteria and HTTP status `200` if successful, or `401` if unauthorised\n\n### Delete recipe\nDELETE `api/recipe/{id}`\n+ Expects authorisation, no body required\n+ Returns HTTP status `204` if successful, or `403`/`404` if not the owner/recipe not found\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimgoetzke%2Fpractice-recipes-db","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkimgoetzke%2Fpractice-recipes-db","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimgoetzke%2Fpractice-recipes-db/lists"}