{"id":18624472,"url":"https://github.com/litsynp/spring-redis-demo","last_synced_at":"2026-01-23T03:53:23.204Z","repository":{"id":109732381,"uuid":"504795872","full_name":"litsynp/spring-redis-demo","owner":"litsynp","description":"Playing with different methods and examples to access Redis and configure it as cache storage on Spring applications.","archived":false,"fork":false,"pushed_at":"2022-06-19T18:09:27.000Z","size":92,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T09:02:32.719Z","etag":null,"topics":["docker","redis","redis-cache","spring-boot","spring-data-jpa","spring-data-redis"],"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/litsynp.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":"2022-06-18T09:11:47.000Z","updated_at":"2022-11-20T17:18:02.000Z","dependencies_parsed_at":"2023-04-04T16:31:56.582Z","dependency_job_id":null,"html_url":"https://github.com/litsynp/spring-redis-demo","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/litsynp%2Fspring-redis-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litsynp%2Fspring-redis-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litsynp%2Fspring-redis-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litsynp%2Fspring-redis-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/litsynp","download_url":"https://codeload.github.com/litsynp/spring-redis-demo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248335565,"owners_count":21086619,"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","redis","redis-cache","spring-boot","spring-data-jpa","spring-data-redis"],"created_at":"2024-11-07T04:29:09.542Z","updated_at":"2026-01-23T03:53:18.182Z","avatar_url":"https://github.com/litsynp.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring Redis Demo\n\n## About\n\nThis project is created to introduce some different methods and examples to access [Redis](https://redis.io/) from Spring applications. This also introduces a way to improve your API with Redis as a cache server.\n\nThe project uses 3 methods to access Redis:\n\n1. [RedisTemplate and opsForValue()](https://www.baeldung.com/spring-data-redis-properties)\n2. [Redis Repository](https://www.baeldung.com/spring-data-redis-tutorial#redis-repository)\n3. [Spring Cache Abstraction](https://www.baeldung.com/spring-cache-tutorial) (`@Cacheable`, `@CachePut`, `@CacheEvict`, and etc.)\n\n## Requirements\n\nThis project set up with [Docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/) to use Redis. If you aren't using Docker, then you should [install up Redis](https://redis.io/docs/getting-started/) on your own.\n\n## Versions\n\nThe versions used in the project are:\n\n- Spring Boot 2.7.0\n- Java 17\n- Gradle 7\n- Redis 6.2\n\n## Spring Dependencies\n\n- Spring Boot Starter Web\n- Spring Boot Starter Data Redis\n- Spring Boot Starter Data JPA\n- Spring Boot Configuration Processor\n- Spring Boot Starter Test\n- Project Lombok\n- H2 Database\n- `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` for Date and Time Serialization and Deserialization\n\n## Run the servers\n\nThe guide provided below is written assuming that you are on a Mac or any Linux machine.\n\n1. Grant permission to shell scripts.\n\n   ```sh\n   $ chmod 700 ./run-redis-server.sh\n   $ chmod 700 ./run-redis-cli.sh\n   ```\n\n2. Run the Redis server.\n\n   ```sh\n   $ ./run-redis-server.sh\n   ```\n\n3. Run the Spring Boot application server using Gradle.\n\n   ```sh\n   $ ./gradlew bootRun\n   ```\n\n4. Execute Redis CLI.\n   ```sh\n   $ ./run-redis-cli.sh\n   ```\n\n**I recommend testing and experimenting with tools like [Postman](https://www.postman.com/) or [curl](https://curl.se/) yourself.**\n\nIf you are done with whatever you do, then close the server and remove the docker container.\n\n```sh\n$ ./stop-redis-server.sh\n```\n\n## Shell Scripts and Docker\n\n- `docker-compose-redis.yml`: Defines Redis service. Sets The Redis password and port (6379) and registers `redis.conf` via volume.\n- `redis.conf`: Configurations for Redis service. Turns off [RDB and AOF](https://stackoverflow.com/questions/28785383/how-to-disable-persistence-with-redis) features. Disables [potentially dangerous commands](https://programmer.group/redis-disable-dangerous-command.html). Sets max client to 50,000.\n- `run-redis-server.sh`: A shell script to stop a running Redis service and builds \u0026 runs a new one.\n- `run-redis-cli.sh`: A shell script to allow access to Redis via Redis CLI.\n    - Make sure to remove line `--include /usr/local/etc/redis/redis.conf` from `docker-compose-redis.yml`, **if you want to use commands like `keys *` and `get \u003ckey\u003e`** to see keys and values put in Redis.\n- `stop-redis-server.sh`: A shell script to stop and remove Redis service.\n\n## Packages and Classes\n\n- `resources/application.yml`: Spring Boot configurations. Configures Redis with host, port and password, and JPA with datasource URL, username and password. Enables H2 console via `/h2-console`.\n\nThe project includes 4 (5, technically) examples to show ways to play with Redis. \n\n- `com.litsynp.redisdemo`\n    - `config`: Holds configurations, especially for Redis.\n        - `ConfigurationPropertiesConfig`: Enables configuration properties.\n        - `ObjectMapperConfig`: Provides customized object mapper for JSON to properly serialize and deserialize `LocalDateTime`. More on this [here](https://www.baeldung.com/jackson-serialize-dates).\n        - `RedisCacheConfig`: Configures caching with Redis. Basically it creates a `CacheManager`to use in caching member. This is used in `com.litsynp.redisdemo.ex4jpacache`. Note that the cache manager registers a customized `ObjectMapper` (similar to that in `ObjectMapperConfig`) as its value serializer. The customized `ObjectMapper` registers `JavaTimeModule` provided by `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` for serialization and deserialization of `LocalDateTime` present in member entity. The entry TTL is set to 3 minutes.\n        - `RedisConfig`: Configures `RedisConnectionFactory` and `RedisTemplate` beans.\n    - `ex1redistemplate`: Example of `RedisTemplate` and `opsForValue`.\n        - `MemberCache`: An example class to be instanced and cached. Currently, this is only used in test codes.\n        - `RedisController`: Uses `StringRedisTemplate` to put String key and String value to Redis.\n    - `ex2redisrepo`: Uses `CrudRepository` for caching member. Currently, this is only used in test codes.\n        - `MemberRedisRepository`: The Redis repository for `RedisMember`.\n        - `RedisMember`: Example member class to be cached. Annotated with `@RedisHash(value = \"member\")` to be saved in \"member:key\" format.\n    - `ex3cache`: An example of how caching with Redis can be done so simply with **cache\n      abstraction**.\n        - `MemberCacheTestController`: Note that there is `Thread.sleep(1500)` in the **GET** API. The API is annotated with `@Cacheable(value = \"member\", cacheManager = \"cacheManager\")`, caching the response of the API. It gets faster the second time you request the same API.\n    - `ex4jpacache`: This example shows how Spring Data JPA and Redis can work together to bring faster responses from APIs, with [cache abstraction](https://www.baeldung.com/spring-cache-tutorial).\n        - `api`: API controllers for comparison.\n            - `MemberApiController`: Member API controller, **not cached**.\n            - `MemberCachedApiController`: Member API controller, **cached with Redis**.\n        - `domain.Member`: Member JPA entity. Saved in `member` table.\n        - `dto.*`: DTOs to be used in API controllers. No further explanations needed.\n        - `exception`: Exceptions thrown from controllers/services.\n        - `repository.MemberRepository`: Spring Data JPA Repository for member entity.\n        - `service`: Member service interface and its implementations.\n            - `MemberService`: Interface for service for member business logics.\n            - `MemberServiceImpl`: Includes Spring Data JPA business logic implementations.\n            - `MemberCacheService`: Calls methods in `MemberServiceImpl` with exactly the same method signatures. The only difference is that the results are **cached**.\n        - `cache.CachedPage`: Wrapper class for `PageImpl`, used for pagination. Without this, you will get `InvalidDefinitionException` when calling `/members` API twice. More on this [here](https://stackoverflow.com/questions/55965523/error-during-deserialization-of-pageimpl-cannot-construct-instance-of-org-spr).\n\n## APIs\n\n- `/v1/str-str` (`RedisController`): Example API for putting and getting String key and String value to Redis.\n- ```\n  Request:\n  POST /v1/str-str\n  {\n    \"key\": \"hello\",\n    \"value\": \"world\"\n  }\n\n  Response:\n  201 Created\n  ```\n\n- ```\n  Request:\n  GET /v1/str-str/{id}\n\n  Response:\n  200 OK\n  {\n    \"key\": \"hello\",\n    \"value\": \"world\",\n    \"success\": \"true\"\n  }\n  ```\n\n- `/v3/members` (`MemberCacheTestController`): Example to save member cache to Redis.\n- ```\n  Request:\n  GET /v3/members?id={id}\n  Saves member with id to Redis.\n\n  Response:\n  200 OK\n  {\n    \"id\": \"XXXXXXX\",\n    \"name\": \"test\",\n    \"age\": 20,\n    \"createdAt\": \"2022-06-20T01:01:01\"\n  }\n\n  Response:\n  201 Created\n  ```\n\n- ```\n  Request:\n  DELETE /v3/members/{id}\n  Deletes member cache with `id` from Redis.\n\n  Response:\n  204 No Content\n  ```\n\n- `/v4/members` (`MemberApiController`): Simple member API using only Spring Data JPA. **Not cached**. Provides CRUD. API and implementation details on the [source code](https://github.com/litsynp/spring-redis-demo/blob/main/src/main/java/com/litsynp/redisdemo/ex4jpacache/api/MemberApiController.java).\n\n- `/v5/members` (`MemberCachedApiController`): Simple member API using both Spring Data JPA and Redis for cache. **Cached**. Provides CRUD. API and implementation details on the [source code](https://github.com/litsynp/spring-redis-demo/blob/main/src/main/java/com/litsynp/redisdemo/ex4jpacache/api/MemberCachedApiController.java).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitsynp%2Fspring-redis-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flitsynp%2Fspring-redis-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitsynp%2Fspring-redis-demo/lists"}