{"id":21672460,"url":"https://github.com/redis-developer/redis-om-spring-skeleton-app","last_synced_at":"2025-10-13T20:40:16.895Z","repository":{"id":42449174,"uuid":"463024201","full_name":"redis-developer/redis-om-spring-skeleton-app","owner":"redis-developer","description":"Redis OM Spring Skeleton App","archived":false,"fork":false,"pushed_at":"2023-07-27T15:07:20.000Z","size":93,"stargazers_count":11,"open_issues_count":3,"forks_count":4,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-12T03:52:58.368Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/redis-developer.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":"2022-02-24T05:45:29.000Z","updated_at":"2024-11-12T12:53:53.000Z","dependencies_parsed_at":"2022-08-28T15:21:23.910Z","dependency_job_id":null,"html_url":"https://github.com/redis-developer/redis-om-spring-skeleton-app","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/redis-developer%2Fredis-om-spring-skeleton-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-developer%2Fredis-om-spring-skeleton-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-developer%2Fredis-om-spring-skeleton-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-developer%2Fredis-om-spring-skeleton-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redis-developer","download_url":"https://codeload.github.com/redis-developer/redis-om-spring-skeleton-app/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514209,"owners_count":21116899,"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-25T13:29:22.890Z","updated_at":"2025-10-13T20:40:11.851Z","avatar_url":"https://github.com/redis-developer.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🍀 Redis OM Spring Skeleton App\n\nRedis OM Spring provides powerful repository and custom object-mapping abstractions built on top of the powerful Spring Data Redis (SDR) framework. This app is a simple started application using Redis OM Spring to map, manipulate and query some simple Spring Data models backed by RedisJSON documents.\n\nCheck out our [workshop video](https://youtu.be/YhQX8pHy3hk) for this project on YouTube.\n\n### Overview\n\nThe app provides a simple model `Person`:\n\n* `id`: An autogenerated `String` using [ULIDs](https://github.com/ulid/spec)\n* `firstName`: A `String` representing their first or given name.\n* `lastName`: A `String` representing theirlast or surname.\n* `age`: An `Integer` representing their age in years.\n* `personalStatement`: A `String` representing a text personal statement containing facts or other biographical information.\n* `homeLoc`: A `org.springframework.data.geo.Point` representing the geo coordinates.\n* `address`: An entity of type `Address` representing the Person's postal address.\n* `skills`: A `Set\u003cString\u003e`, representing a collection of Strings representing skills the person has.\n\n#### Mapping Entities to JSON\n\nThe `Person` model is annotated with `@Document`, this enables the models to be saved as RedisJSON documents.\nThe individuals fields that will be used to create the entity search index are annotated with `@Indexed` or\n`@Searchable` (for full-text search capable text fields).\n\n```java\n@Document\npublic class Person {\n  @Id @Indexed\n  private String id;\n\n  @Indexed\n  private String firstName;\n\n  @Indexed\n  private String lastName;\n\n  @Indexed\n  private Integer age;\n\n  @Searchable\n  private String personalStatement;\n\n  @Indexed\n  private Point homeLoc;\n\n  @Indexed\n  private Address address;\n\n  @Indexed\n  private Set\u003cString\u003e skills;\n}\n```\n\nFor example, saving the above object using a repository (see below) you'll get a JSON document under the Redis key `com.redis.om.skeleton.models.Person:01FXD97WTHNYFQEA56YQ27BNQ6`:\n\n```json\n{\n  \"id\": \"01FXD97WTHNYFQEA56YQ27BNQ6\",\n  \"firstName\": \"Elizabeth\",\n  \"lastName\": \"Olsen\",\n  \"age\": 32,\n  \"personalStatement\": \"You Guys Know I Can Move Things With My Mind, Right?\",\n  \"homeLoc\": \"40.6976701,-74.2598641\",\n  \"address\": {\n    \"houseNumber\": \"20\",\n    \"street\": \"W 34th St\",\n    \"city\": \"New York\",\n    \"state\": \"NY\",\n    \"postalCode\": \"10001\",\n    \"country\": \"US\"\n  },\n  \"skills\": [\n    \"loyalty\",\n    \"magic\"\n  ]\n}\n```\n\nThe resulting JSON has a generated value for the `id` field using a [ULIDs](https://github.com/ulid/spec). Note that\nthe `homeLoc` field is mapped to the lon-lat format expected by Redis, and the set of `skills` is mapped into a JSON array.\n\n### The SpringBoot App\n\nUse the `@EnableRedisDocumentRepositories` annotation to scan for `@Document` annotated Spring models,\nInject repositories beans implementing `RedisDocumentRepository` which you can use for CRUD operations and custom queries (all by declaring Spring Data Query Interfaces):\n\n```java\n@SpringBootApplication\n@EnableRedisDocumentRepositories(basePackages = \"com.redis.om.skeleton.*\")\npublic class SkeletonApplication {\n}\n```\n\n### 🧰 The Repository\n\nRedis OM Spring data repository's goal, like other Spring Data repositories, is to significantly reduce the amount of boilerplate code required to implement data access. Simply create a Java interface\nthat extends `RedisDocumentRepository` that takes the domain class to manage as well as the ID type of the domain class as type arguments. `RedisDocumentRepository` extends Spring Data's `PagingAndSortingRepository`.\n\nDeclare query methods on the interface. You can both, expose CRUD methods or create declarations for complex queries that Redis OM Spring will fullfil at runtime:\n\n```java\npublic interface PeopleRepository extends RedisDocumentRepository\u003cPerson, String\u003e {\n  // Find people by age range\n  Iterable\u003cPerson\u003e findByAgeBetween(int minAge, int maxAge);\n\n  // Draws a circular geofilter around a spot and returns all people in that radius\n  Iterable\u003cPerson\u003e findByHomeLoc(Point point, Distance distance);\n\n  // Find people by their first and last name\n  Iterable\u003cPerson\u003e findByFirstNameAndLastName(String firstName, String lastName);\n\n  // Performs full text search on a person's personal Statement\n  Iterable\u003cPerson\u003e searchByPersonalStatement(String text);\n\n  // ...\n}\n```\n\nThe repository proxy has two ways to derive a store-specific query from the method name:\n\n- By deriving the query from the method name directly.\n- By using a manually defined query using the `@Query` or `@Aggregation` annotations.\n\n### CRUD Operations\n\nYou can inject a Repository and perform the basic CRUD operations as well as any custom queries you've defined:\n\n```java\n@Autowired\nPeopleRepository repo;\n\n@PostMapping(\"new\")\nPerson create(@RequestBody Person newPerson) {\n  return repo.save(newPerson);\n}\n```\n\n### 🚤 Querying with Entity Streams\n\nRedis OM Spring Entity Streams provides a Java 8 Streams interface to Query Redis JSON documents using RediSearch. Entity Streams allow you to process data in a typesafe declarative way similar to SQL statements. Streams can be used to express a query as a chain of operations.\n\nEntity Streams in Redis OM Spring provide the same semantics as Java 8 streams. Streams can be made of Redis Mapped entities (`@Document`) or one or more properties of an Entity. Entity Streams progressively build the query until a terminal operation is invoked (such as `collect`). Whenever a Terminal operation is applied to a Stream, the Stream cannot accept additional operations to its pipeline and it also means that the Stream is started.\n\nLet's start with a simple example, a Spring `@Service` which includes `EntityStream` to query for instances of the mapped class `Person`:\n\n```java\npackage com.redis.om.skeleton.services;\n\nimport java.util.stream.Collectors;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\nimport com.redis.om.skeleton.models.Person;\nimport com.redis.om.skeleton.models.Person$;\nimport com.redis.om.spring.search.stream.EntityStream;\n\n@Service\npublic class PeopleService {\n  @Autowired\n  EntityStream entityStream;\n\n  // Find all people\n  public Iterable\u003cPerson\u003e findAllPeople(int minAge, int maxAge) {\n    return entityStream //\n        .of(Person.class) //\n        .collect(Collectors.toList());\n  }\n\n}\n```\n\nThe `EntityStream` is injected into the `PeopleService` using `@Autowired`. We can then get a stream for `Person` objects by using `entityStream.of(Person.class)`. At this point the stream represents the equivalent of a `SELECT * FROM Person` on a relational database. The call to `collect` will then execute the underlying query and return a collection of all `Person` objects in Redis.\n\n#### 👭 Entity Meta-model\n\nTo produce more elaborate queries, you're provided with a generated meta-model, which is a class with the same name as your model but ending with a dollar sign. In the\nexample below, our entity model is `Person` therefore we get a meta-model named `Person$`. With the meta-model you have access to the operations related to the\nunderlying search engine field. For example, in the example we have an `age` property which is an integer. Therefore our metamodel has an `AGE` property which has\nnumeric operations we can use with the stream's `filter` method such as `between`.\n\n```java\n// Find people by age range\npublic Iterable\u003cPerson\u003e findByAgeBetween(int minAge, int maxAge) {\n  return entityStream //\n      .of(Person.class) //\n      .filter(Person$.AGE.between(minAge, maxAge)) //\n      .sorted(Person$.AGE, SortOrder.ASC) //\n      .collect(Collectors.toList());\n}\n```\n\nIn this example we also make use of the Streams `sorted` method to declare that our stream will be sorted by the `Person$.AGE` in `ASC`ending order.\n\n### 💾 Get the Source Code\n\nClone the repository from GitHub:\n\n```bash\n$ git clone https://github.com/redis-developer/redis-om-spring-skeleton-app\n$ cd redis-om-spring-skeleton-app\n```\n\n### 🚀 Launch Redis\n\n#### 🥞Redis Stack on Docker Locally\n\nRedis OM Spring relies on the power of the [RediSearch][redisearch-url] and [RedisJSON][redis-json-url] modules.\nWe have provided a docker compose YAML file for you to quickly get started. To launch the docker compose application, on the command line (or via Docker Desktop), clone this repository and run (from the root folder):\n\n```bash\ndocker compose up\n```\n\nThis launches Redis Stack; Redis Stack Server on port 6379, and Redis Insight 8001.\n\n#### 🌥️Redis Cloud\n\nIf you're using Redis Enterprise Cloud, you'll need the hostname, port number, and password for your database.  Use these to set the `application.properties` configuration like this:\n\n```bash\nspring.data.redis.host=\u003chost\u003e\nspring.data.redis.port=\u003cport\u003e\nspring.data.redis.password=\u003cpassword\u003e\nspring.data.redis.username=\u003cusername\u003e\n```\n\nFor example if your Redis Enterprise Cloud database is at port `9139` on host `enterprise.redis.com` and your password is `5uper53cret` then you'd set `REDIS_OM_URL` as follows:\n\n```bash\nspring.data.redis.host=enterprise.redis.com\nspring.data.redis.port=9139\nspring.data.redis.password=5uper53cret\nspring.data.redis.username=default\n```\n\n## 📝 Prerequisites\n\n* Java 17 or higher\n* Spring Boot 3.0.2 \n* A [Redis](https://redis.io) database with the [RediSearch](https://redisearch.io) module version TODO or higher installed.  We've provided a `docker-compose.yml` with Redis Stack for this. You can also [sign up for a free 30Mb database with Redis Enterprise Cloud](https://redis.com/try-free/) - be sure to check the box to configure a Redis Stack instance, follow [this guide](https://developer.redis.com/create/rediscloud/).\n* [curl](https://curl.se/), or [Postman](https://www.postman.com/) - to send HTTP requests to the application.  We'll provide examples using curl in this document.\n* Optional: [RedisInsight](https://redis.com/redis-enterprise/redis-insight/), a free data visualization and database management tool for Redis.  When downloading RedisInsight, be sure to select version 2.x.\n\n## 🏃Run the App\n\n```bash\n./mvnw spring-boot:run\n```\n\n### 🧭Interact with the API\n\nYou can interact with the API directly with CURL or through the [Swagger interface](http://localhost:8080/swagger-ui/index.html).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredis-developer%2Fredis-om-spring-skeleton-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredis-developer%2Fredis-om-spring-skeleton-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredis-developer%2Fredis-om-spring-skeleton-app/lists"}