### Build Spring Data REST with Maven Wrapper Source: https://github.com/spring-projects/spring-data-rest/blob/main/README.adoc Execute this command to clean and install the project using the Maven wrapper. Ensure you have JDK 17 installed. ```bash $ ./mvnw clean install ``` -------------------------------- ### Exposed Repository and Method Example Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Example of a repository and method explicitly exposed using annotations. Methods without @RestResource are not exposed. ```java // Only this repository will be exposed @RepositoryRestResource(path = "people") public interface PersonRepository extends CrudRepository { // Only this method will be exposed under /people/search/byName @RestResource(path = "byName") List findByLastName(@Param("name") String name); // This method is NOT exposed (no @RestResource) List findByAge(int age); } ``` -------------------------------- ### Discover Root Resources via HTTP GET Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/repository-resources.adoc Issue an HTTP GET request to the root URL to discover available resources. The response, in HAL format, contains links to top-level resources like 'orders' and 'profile'. ```http curl -v http://localhost:8080/ < HTTP/1.1 200 OK < Content-Type: application/hal+json { "_links" : { "orders" : { "href" : "http://localhost:8080/orders" }, "profile" : { "href" : "http://localhost:8080/api/alps" } } } ``` -------------------------------- ### Non-Exposed Repository Example Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Example of a repository that is not exposed because it lacks the @RepositoryRestResource annotation. ```java // This repository is NOT exposed (no @RepositoryRestResource) public interface InternalRepository extends CrudRepository { } ``` -------------------------------- ### Custom ALPS Descriptions using Properties Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/metadata.adoc This example demonstrates how to define custom descriptions for resources and their fields in ALPS metadata by using a `rest-messages.properties` file. ```properties rest.description.person=A collection of people rest.description.person.id=primary key used internally to store a person (not for RESTful usage) rest.description.person.firstName=Person's first name rest.description.person.lastName=Person's last name rest.description.person.address=Person's address ``` -------------------------------- ### Default Person Resource Representation (with Address Repository) Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/projections-excerpts.adoc Example HAL document for a Person resource when an Address repository is defined. The address is represented as a link. ```javascript { "firstName" : "Frodo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "http://localhost:8080/persons/1" }, "address" : { "href" : "http://localhost:8080/persons/1/address" } } } ``` -------------------------------- ### Enable JSONP with Default Callback Parameter Source: https://github.com/spring-projects/spring-data-rest/wiki/JSONP-Support-in-Spring-Data-REST To enable JSONP, pass the `callback` URL parameter to your request. This example shows how to query for people by name. ```bash curl -v http://localhost:8080/people/search/findByName?name=John+Doe&callback=my_json_callback ``` -------------------------------- ### Conditional GET Request with If-None-Match Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/etags-and-other-conditionals.adoc Employ the If-None-Match header with GET requests to conditionally retrieve resources. If the header's ETag matches the server's current ETag, a 304 Not Modified status is returned, saving bandwidth. ```shell curl -v -H 'If-None-Match: ' ... ``` -------------------------------- ### Search Resource - GET Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/repository-resources.adoc Returns links for all query methods exposed by a repository. Supports application/hal+json and application/json media types. ```APIDOC ## GET /api/search ### Description Returns a list of links pointing to the individual query method resources. ### Method GET ### Endpoint /api/search ### Parameters None ### Response #### Success Response (200) - Links to individual query method resources. #### Supported Media Types - application/hal+json - application/json ``` -------------------------------- ### JSONP Response Example Source: https://github.com/spring-projects/spring-data-rest/wiki/JSONP-Support-in-Spring-Data-REST A typical JSONP response wraps the data in a JavaScript function call specified by the `callback` parameter. ```javascript my_jsonp_callback({ "results": [ ... ], "_links": [ ... ] }) ``` -------------------------------- ### Custom RepositoryRestController Example Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/overriding-sdr-response-handlers.adoc Use @RepositoryRestController to create custom handlers for specific resources, leveraging Spring Data REST's features. This example shows how to define a custom GET endpoint that fetches data, performs post-processing, and returns a CollectionModel with self-links. ```java @RepositoryRestController class ScannerController { private final ScannerRepository repository; ScannerController(ScannerRepository repository) { // <1> this.repository = repository; } @GetMapping(path = "/scanners/search/producers") // <2> ResponseEntity getProducers() { List producers = repository.listProducers(); // <3> // do some intermediate processing, logging, etc. with the producers CollectionModel resources = CollectionModel.of(producers); // <4> resources.add(linkTo(methodOn(ScannerController.class).getProducers()).withSelfRel()); // <5> // add other links as needed return ResponseEntity.ok(resources); // <6> } } ``` -------------------------------- ### Default Person Resource Representation (without Address Repository) Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/projections-excerpts.adoc Example representation of a Person resource when no separate Address repository is defined. Address details are embedded. ```javascript { "firstName" : "Frodo", "lastName" : "Baggins", "address" : { "street": "Bag End", "state": "The Shire", "country": "Middle Earth" }, "_links" : { "self" : { "href" : "http://localhost:8080/persons/1" } } } ``` -------------------------------- ### Default Query Method Exposure Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/configuring-the-rest-url-path.adoc Query methods are exposed under the 'search' resource by default, using their method name. This example shows a repository with a query method. ```java interface PersonRepository extends CrudRepository { List findByName(String name); } ``` -------------------------------- ### Define Excerpt Projection for Collections Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Create a concise projection for entities displayed in collections. This example shows a Book excerpt. ```java // Projection for excerpts in collections @Projection(name = "excerpt", types = Book.class) public interface BookExcerpt { String getTitle(); // Excludes author details, publication date, etc. } ``` -------------------------------- ### Fetch Person Links using Compact JSON Source: https://github.com/spring-projects/spring-data-rest/wiki/Embedded-Entity-references-in-complex-object-graphs Example cURL command to fetch a list of Person links using the compact JSON format. This is useful for obtaining entity references. ```bash curl -v -H "Accept: application/x-spring-data-compact+json" http://localhost:8080/people ``` -------------------------------- ### Association Resource Supported Methods Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/repository-resources.adoc Details the supported HTTP methods for association resources, including GET, PUT, POST, and DELETE. ```APIDOC ## GET /api/items/{id}/association ### Description Retrieves the state of the association resource. ### Method GET ### Endpoint /api/items/{id}/association ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the item. - **association** (string) - Required - The name of the association. ### Response #### Success Response (200) - **body** (object) - The state of the association resource. ## PUT /api/items/{id}/association ### Description Replaces the state of the association resource. ### Method PUT ### Endpoint /api/items/{id}/association ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the item. - **association** (string) - Required - The name of the association. #### Request Body - **field** (any) - Required - The new state of the association resource. ### Response #### Success Response (200 or 204) - **body** (object) - The updated association resource representation (if Accept header is present). - **status** (integer) - 200 OK if a body is returned, 204 No Content if no body is returned. ## POST /api/items/{id}/association ### Description Creates or updates an association. ### Method POST ### Endpoint /api/items/{id}/association ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the item. - **association** (string) - Required - The name of the association. #### Request Body - **field** (any) - Required - The data for the association. ### Response #### Success Response (200 or 201) - **body** (object) - The created or updated association resource representation. - **status** (integer) - 200 OK or 201 Created. ## DELETE /api/items/{id}/association ### Description Deletes the association resource. ### Method DELETE ### Endpoint /api/items/{id}/association ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the item. - **association** (string) - Required - The name of the association. ### Response #### Success Response (200 or 204) - **body** (object) - The deleted association resource representation (if Accept header is present). - **status** (integer) - 200 OK if a body is returned, 204 No Content if no body is returned. ``` -------------------------------- ### POST JSON to Create New Address Source: https://github.com/spring-projects/spring-data-rest/wiki/Embedded-Entity-references-in-complex-object-graphs Example cURL command to POST the JSON payload to create a new Address instance with a referenced Person. ```bash curl -v -X POST -d '...json data...' http://localhost:8080/address ``` -------------------------------- ### Person Resource JSON Schema Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/metadata.adoc This is an example of the JSON Schema for the 'Person' resource. It details the properties, their types, and read-only status, useful for understanding the data structure and validation. ```json { "title" : "org.springframework.data.rest.webmvc.jpa.Person", "properties" : { "firstName" : { "readOnly" : false, "type" : "string" }, "lastName" : { "readOnly" : false, "type" : "string" }, "siblings" : { "readOnly" : false, "type" : "string", "format" : "uri" }, "created" : { "readOnly" : false, "type" : "string", "format" : "date-time" }, "father" : { "readOnly" : false, "type" : "string", "format" : "uri" }, "weight" : { "readOnly" : false, "type" : "integer" }, "height" : { "readOnly" : false, "type" : "integer" } }, "descriptors" : { }, "type" : "object", "$schema" : "https://json-schema.org/draft-04/schema#" } ``` -------------------------------- ### Example Domain Class with Interface Field Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/representations.adoc A sample domain entity class that includes a field of an interface type. This demonstrates a scenario where custom Jackson configuration might be needed for abstract type resolution. ```java @Entity public class MyEntity { @OneToMany private List interfaces; } ``` -------------------------------- ### Repository Link Rel Example Output Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/configuring-the-rest-url-path.adoc This JSON snippet illustrates the effect of customizing the repository's 'rel' attribute, changing the top-level link name from the default to 'people'. ```javascript { "_links" : { "people" : { "href" : "http://localhost:8080/people" }, … } } ``` -------------------------------- ### Default Query Method Exposure Source: https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path Query methods are exposed under the 'search' resource by default, using their method name. For example, findByName is exposed under /person/search/findByName. ```java public interface PersonRepository extends CrudRepository { public List findByName(String name); } ``` -------------------------------- ### Compact JSON Response with Person Links Source: https://github.com/spring-projects/spring-data-rest/wiki/Embedded-Entity-references-in-complex-object-graphs Example compact JSON response containing links to Person entities. These links are used to reference existing Person objects. ```json { "links" : [ { "rel" : "people.Person", "href" : "http://localhost:8080/people/2" }, { "rel" : "people.Person", "href" : "http://localhost:8080/people/1" }, { "rel" : "people.search", "href" : "http://localhost:8080/people/search" } ], "content" : [ ], "page" : { "number" : 1, "size" : 20, "totalPages" : 1, "totalElements" : 2 } } ``` -------------------------------- ### Default Query Method Link Rel Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/configuring-the-rest-url-path.adoc In HAL format, query methods are exposed with a 'rel' attribute matching their method name. This example shows the default JSON output for a query method link. ```javascript { "_links" : { "findByName" : { "href" : "http://localhost:8080/persons/search/findByName" } } } ``` -------------------------------- ### Query Method Resource - GET Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/repository-resources.adoc Runs an exposed query through an individual query method on the repository interface. Supports pagination parameters. Supports application/hal+json and application/json media types. ```APIDOC ## GET /api/query/{methodName} ### Description Returns the result of the query executed by the specified query method. ### Method GET ### Endpoint /api/query/{methodName} ### Parameters #### Query Parameters - **page** (integer) - Optional - The page number to access (0 indexed, defaults to 0). - **size** (integer) - Optional - The page size requested (defaults to 20). - **sort** (string) - Optional - A collection of sort directives in the format `($propertyname,)+[asc|desc]?`. ### Response #### Success Response (200) - The result of the query. #### Supported Media Types - application/hal+json - application/json ``` -------------------------------- ### JSON Payload for Creating an Address with Person Reference Source: https://github.com/spring-projects/spring-data-rest/wiki/Embedded-Entity-references-in-complex-object-graphs Example JSON payload for creating a new Address. It includes a direct link to an existing Person entity to satisfy the `optional = false` constraint. ```json { "postalCode": "12345", "province": "MO", "lines": ["1 W 1st St."], "city": "Univille", "person": "http://localhost:8080/people/1" } ``` -------------------------------- ### Person Resource Representation with NoAddresses Projection Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/projections-excerpts.adoc Example HAL document for a Person resource using the 'noAddresses' projection. Address information is omitted, and the self link is templated. ```javascript { "firstName" : "Frodo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "http://localhost:8080/persons/1{?projection}", "templated" : true }, "address" : { "href" : "http://localhost:8080/persons/1/address" } } } ``` -------------------------------- ### Interact with Spring Data REST API using curl Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Examples demonstrating common REST API operations like discovery, creation, retrieval, and updates (PUT, PATCH) using curl. Assumes the API is running on localhost:8080. ```bash # Get the root resource (API discovery) curl -X GET http://localhost:8080/api # Response: # { # "_links": { # "people": { "href": "http://localhost:8080/api/people{?page,size,sort}" }, # "books": { "href": "http://localhost:8080/api/books" } # } # } # Create a new person (POST) curl -X POST http://localhost:8080/api/people \ -H "Content-Type: application/json" \ -d '{"firstName": "John", "lastName": "Doe"}' # Response: HTTP 201 Created # Location: http://localhost:8080/api/people/1 # Get a person by ID curl -X GET http://localhost:8080/api/people/1 # Response: # { # "firstName": "John", # "lastName": "Doe", # "_links": { # "self": { "href": "http://localhost:8080/api/people/1" }, # "siblings": { "href": "http://localhost:8080/api/people/1/siblings" } # } # } # Update a person (PUT - full replacement) curl -X PUT http://localhost:8080/api/people/1 \ -H "Content-Type: application/json" \ -d '{"firstName": "John", "lastName": "Smith"}' # Partial update (PATCH with JSON Merge Patch) curl -X PATCH http://localhost:8080/api/people/1 \ -H "Content-Type: application/merge-patch+json" \ -d '{"lastName": "Smith"}' # Partial update (PATCH with JSON Patch) curl -X PATCH http://localhost:8080/api/people/1 \ -H "Content-Type: application/json-patch+json" \ -d '[{"op": "replace", "path": "/lastName", "value": "Smith"}]' ``` -------------------------------- ### Custom JSONP Callback Parameter Usage Source: https://github.com/spring-projects/spring-data-rest/wiki/JSONP-Support-in-Spring-Data-REST After configuring a custom `jsonpParamName`, use that parameter in your request URL. This example uses the configured "jsonp" parameter. ```bash curl -v http://localhost:8080/people/search/findByName?name=John+Doe&jsonp=my_json_callback ``` -------------------------------- ### HAL Document with Inline Address Data Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/projections-excerpts.adoc Example of a HAL document where the 'address' data is included inline due to the configured excerpt projection. The link to the address resource is still provided. ```javascript { "firstName" : "Frodo", "lastName" : "Baggins", "address" : { "street": "Bag End", "state": "The Shire", "country": "Middle Earth" }, "_links" : { "self" : { "href" : "http://localhost:8080/persons/1" }, "address" : { "href" : "http://localhost:8080/persons/1/address" } } } ``` -------------------------------- ### Sort Results by Name Descending Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/paging-and-sorting.adoc Use the `sort` URL parameter to order results by a specific property. Append `,desc` for descending order. This example sorts people by name. ```http curl -v "http://localhost:8080/people/search/nameStartsWith?name=K&sort=name,desc" ``` -------------------------------- ### Customize Item Resource URIs with EntityLookupSupport (Older Java) Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing-sdr.adoc Implement EntityLookupSupport to customize item resource URIs when not using Java 8+. This involves defining how to get the resource identifier and how to look up entities. ```java @Component public class UserEntityLookup extends EntityLookupSupport { private final UserRepository repository; public UserEntityLookup(UserRepository repository) { this.repository = repository; } @Override public Serializable getResourceIdentifier(User entity) { return entity.getUsername(); } @Override public Object lookupEntity(Serializable id) { return repository.findByUsername(id.toString()); } } ``` -------------------------------- ### Enable JSONP Error Handling Source: https://github.com/spring-projects/spring-data-rest/wiki/JSONP-Support-in-Spring-Data-REST To handle server errors with JSONP, set the `jsonpOnErrParamName` property in `RepositoryRestConfiguration`. This example shows how to trigger error handling with an "errback" parameter. ```bash curl -v -d '...bad json data...' http://localhost:8080/people?errback=my_jsonp_error_handler ``` -------------------------------- ### Query Spring Data REST API using curl Source: https://github.com/spring-projects/spring-data-rest/blob/main/README.adoc Example of how to query a custom search resource ('byFirstname') exposed by Spring Data REST using curl. Demonstrates filtering by firstname and sorting. ```bash curl -v "http://localhost:8080/people/search/byFirstname?firstname=Oliver*&sort=name,desc" ``` -------------------------------- ### Configure JSONP Callback Parameter Name Source: https://github.com/spring-projects/spring-data-rest/wiki/JSONP-Support-in-Spring-Data-REST Customize the URL parameter name for JSONP callbacks by setting the `jsonpParamName` property in `RepositoryRestConfiguration`. This JavaConfig example sets it to "jsonp". ```java @Bean public RepositoryRestConfiguration restConfig() { return new RepositoryRestConfiguration(). setJsonpParamName("jsonp"); } ``` -------------------------------- ### Build Reference Documentation with Maven Wrapper Source: https://github.com/spring-projects/spring-data-rest/blob/main/README.adoc Use this command to build the project and its reference documentation without running tests. The documentation will be generated in `target/site/reference/html/index.html`. ```bash $ ./mvnw clean install -Pantora ``` -------------------------------- ### Discover Available Search Methods Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Fetch the available search methods for a given resource. ```bash curl -X GET http://localhost:8080/api/people/search ``` -------------------------------- ### Get Siblings of a Person Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Retrieve the associated siblings for a given person. ```bash curl -X GET http://localhost:8080/api/people/1/siblings ``` -------------------------------- ### Person Entity Definition Source: https://github.com/spring-projects/spring-data-rest/wiki/Embedded-Entity-references-in-complex-object-graphs Defines a Person entity. This is a basic entity definition used in examples. ```java @Entity public class Person { // ... person's properties } ``` -------------------------------- ### Get Person with Projection Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Retrieve a specific person's data using a projection to control the fields returned. ```bash curl -X GET "http://localhost:8080/api/people/1?projection=summary" ``` -------------------------------- ### List People with Pagination and Sorting Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Retrieve a list of people with options for pagination (page and size) and sorting (field and direction). ```bash curl -X GET "http://localhost:8080/api/people?page=0&size=10&sort=lastName,asc" ``` -------------------------------- ### Add Multiple Associations Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Add multiple associations to a resource simultaneously using 'text/uri-list' with multiple URIs. ```bash curl -X POST http://localhost:8080/api/people/1/siblings \ -H "Content-Type: text/uri-list" \ -d "http://localhost:8080/api/people/2 http://localhost:8080/api/people/3" ``` -------------------------------- ### Default Repository Exposure Source: https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path By default, a CrudRepository is exposed using its class name stripped of 'Repository'. For example, PersonRepository is exposed under /person/. ```java public interface PersonRepository extends CrudRepository {} ``` -------------------------------- ### Fetch First Page with Page Size 5 Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/paging-and-sorting.adoc This `curl` command fetches the first page of results with a page size of 5. Note the use of quotes around the URL when using `&`. ```bash curl localhost:8080/people?size=5 ``` -------------------------------- ### Implement Person ResourceProcessor Source: https://github.com/spring-projects/spring-data-rest/wiki/Customizing-the-JSON-output Use this to add custom links to a Person resource. Ensure you have Spring HATEOAS configured. ```java @Bean public ResourceProcessor> personProcessor() { return new ResourceProcessor>() { @Override public Resource process(Resource resource) { resource.add(new Link("http://localhost:8080/people", "added-link")); return resource; } }; } ``` -------------------------------- ### Customizing Repository Path Source: https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path Use the @RestResource annotation at the class level to change the path under which a Repository is exposed. This example changes the path to 'people'. ```java @RestResource(path = "people") public interface PersonRepository extends CrudRepository {} ``` -------------------------------- ### HAL Response for First Page Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/paging-and-sorting.adoc The HAL response for the first page includes `_links` for `self` and `next`, and a `page` object detailing pagination information like size, total elements, total pages, and current number. ```json { "_links" : { "self" : { "href" : "http://localhost:8080/persons{&sort,page,size}", "templated" : true }, "next" : { "href" : "http://localhost:8080/persons?page=1&size=5{&sort}", "templated" : true } }, "_embedded" : { … data … }, "page" : { "size" : 5, "totalElements" : 50, "totalPages" : 10, "number" : 0 } } ``` -------------------------------- ### Search People by First Name Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Perform a search for people using query methods, specifying search parameters like first name, page, and size. ```bash curl -X GET "http://localhost:8080/api/people/search/firstname?firstname=John&page=0&size=20" ``` -------------------------------- ### Link to All Search Resources Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/integration.adoc Retrieves a list of links for all finder methods exposed by the repository corresponding to the specified entity type. Supports additional parameters for paging and sorting. ```java entityLinks.linksToSearchResources(Person.class) ``` -------------------------------- ### Customizing Query Method Path Source: https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path Use the @RestResource annotation on a query method to change its exposed path. This example changes the query method path to 'names'. ```java @RestResource(path = "people") public interface PersonRepository extends CrudRepository { @RestResource(path = "names") public List findByName(String name); } ``` -------------------------------- ### Define Domain with Interface Field Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/custom-jackson-deserialization.adoc Example of a domain entity that uses an interface for a collection field. Jackson requires explicit configuration to instantiate implementations for interfaces. ```java @Entity public class MyEntity { @OneToMany private List interfaces; } ``` -------------------------------- ### JSONP Error Response Example Source: https://github.com/spring-projects/spring-data-rest/wiki/JSONP-Support-in-Spring-Data-REST When JSONP error handling is enabled, errors are returned as a JavaScript function call with the HTTP status code and error message. ```javascript my_jsonp_error_handler(400, { "message": "Validation failed on property 'name'!", "cause": { ... } }) ``` -------------------------------- ### Set Page Size with 'limit' Parameter Source: https://github.com/spring-projects/spring-data-rest/wiki/Paging-and-Sorting When accessing a list of all entities from a repository that extends PagingAndSortingRepository, a 'limit' parameter can be added to the URL to specify the page size. ```http http://localhost:8080/people/?limit=50 ``` -------------------------------- ### Fetch Second Page with Page Size 5 Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/paging-and-sorting.adoc This `curl` command fetches the second page (page number 1) of results with a page size of 5. The response includes `prev` and `next` links. ```bash $ curl "http://localhost:8080/persons?page=1&size=5" ``` -------------------------------- ### Customizing Repository Path with @RepositoryRestResource Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/configuring-the-rest-url-path.adoc Use the @RepositoryRestResource annotation at the class level to change the base path for a repository. The example sets the path to "people". ```java @RepositoryRestResource(path = "people") interface PersonRepository extends CrudRepository {} ``` -------------------------------- ### Default Repository Exposure Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/configuring-the-rest-url-path.adoc By default, Spring Data REST exposes repositories using the pluralized name of the domain class. This example shows a basic repository definition. ```java interface PersonRepository extends CrudRepository {} ``` -------------------------------- ### Extend PagingAndSortingRepository for Paging Support Source: https://github.com/spring-projects/spring-data-rest/wiki/Paging-and-Sorting To enable paging for your repositories, extend the PagingAndSortingRepository interface. This interface provides methods that accept a Pageable object to manage the number and page of results. ```java public Page findAll(Pageable pageable); ``` -------------------------------- ### Query Family Members using curl Source: https://github.com/spring-projects/spring-data-rest/wiki/Example-API-usage-with-curl Use a GET request to retrieve the members of a family. The response is in JSON format and includes a list of associated people with their links. ```bash $ curl -v http://localhost:8080/family/1/members ``` ```json { "links" : [ ], "content" : [ { "links" : [ { "rel" : "family.Family.members.Person", "href" : "http://localhost:8080/family/1/members/1" }, { "rel" : "peeps.Person.addresses", "href" : "http://localhost:8080/people/1/addresses" }, { "rel" : "peeps.Person.profiles", "href" : "http://localhost:8080/people/1/profiles" }, { "rel" : "self", "href" : "http://localhost:8080/people/1" } ], "name" : "John Doe" }, { "links" : [ { "rel" : "peeps.Person.addresses", "href" : "http://localhost:8080/people/2/addresses" }, { "rel" : "family.Family.members.Person", "href" : "http://localhost:8080/family/1/members/2" }, { "rel" : "peeps.Person.profiles", "href" : "http://localhost:8080/people/2/profiles" }, { "rel" : "self", "href" : "http://localhost:8080/people/2" } ], "name" : "Jane Doe" } ] } ``` -------------------------------- ### Item Resource Supported Methods Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/repository-resources.adoc Details the supported HTTP methods for item resources, including HEAD, PUT, PATCH, and DELETE. ```APIDOC ## HEAD /api/items/{id} ### Description Checks for the availability of an item resource. ### Method HEAD ### Endpoint /api/items/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the item. ### Response #### Success Response (200) No specific body content is defined for HEAD requests. ## PUT /api/items/{id} ### Description Replaces the state of the target resource with the supplied request body. ### Method PUT ### Endpoint /api/items/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the item. #### Request Body - **field** (any) - Required - The new state of the resource. ### Response #### Success Response (200 or 204) - **body** (object) - The updated resource representation (if Accept header is present). - **status** (integer) - 200 OK if a body is returned, 204 No Content if no body is returned. #### Error Response - **405 Method Not Allowed**: If the save method is not exported or present. ## PATCH /api/items/{id} ### Description Partially updates the resource's state. ### Method PATCH ### Endpoint /api/items/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the item. #### Request Body - **field** (any) - Required - The partial state of the resource to update. ### Response #### Success Response (200 or 204) - **body** (object) - The updated resource representation (if Accept header is present). - **status** (integer) - 200 OK if a body is returned, 204 No Content if no body is returned. #### Error Response - **405 Method Not Allowed**: If the save method is not exported or present. ## DELETE /api/items/{id} ### Description Deletes the exposed resource. ### Method DELETE ### Endpoint /api/items/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the item. ### Response #### Success Response (200 or 204) - **body** (object) - The deleted resource representation (if Accept header is present). - **status** (integer) - 200 OK if a body is returned, 204 No Content if no body is returned. #### Error Response - **405 Method Not Allowed**: If the delete method is not exported or present. ``` -------------------------------- ### Customizing Repository Link Rel Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/configuring-the-rest-url-path.adoc The 'rel' property on the @RepositoryRestResource annotation can be used to customize the top-level link name for the repository. This example sets the rel to "people". ```java @RepositoryRestResource(path = "people", rel = "people") interface PersonRepository extends CrudRepository { @RestResource(path = "names", rel = "names") List findByName(String name); } ``` -------------------------------- ### Customizing Rel Attribute for Query Method Source: https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path Use the 'rel' property on the @RestResource annotation to change the 'rel' attribute in links. This example sets the rel to 'names' for the findByName method. ```java @RestResource(path = "people") public interface PersonRepository extends CrudRepository { @RestResource(path = "names", rel = "names") public List findByName(String name); } ``` -------------------------------- ### Configure Restricted Repository Exposure Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Implement RepositoryRestConfigurer to disable default exposure, requiring explicit annotations for repositories and methods. ```java import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; import org.springframework.web.servlet.config.annotation.CorsRegistry; @Configuration public class RestrictedExposureConfig implements RepositoryRestConfigurer { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) { // Disable default exposure completely // Repositories must be annotated with @RepositoryRestResource // Methods must be annotated with @RestResource to be exposed config.disableDefaultExposure(); } } ``` -------------------------------- ### Global CORS Configuration with RepositoryRestConfigurer Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/configuring-cors.adoc Define global CORS configuration by implementing `RepositoryRestConfigurer` and overriding the `configureRepositoryRestConfiguration` method. This allows for centralized configuration of CORS mappings, origins, methods, headers, and max age. ```java @Component public class SpringDataRestCustomization implements RepositoryRestConfigurer { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) { cors.addMapping("/person/**") .allowedOrigins("http://domain2.example") .allowedMethods("PUT", "DELETE") .allowedHeaders("header1", "header2", "header3") .exposedHeaders("header1", "header2") .allowCredentials(false).maxAge(3600); } } ``` -------------------------------- ### Query Method Resource - HEAD Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/repository-resources.adoc Returns whether a query method resource is available. ```APIDOC ## HEAD /api/query/{methodName} ### Description Returns whether a query method resource is available. ### Method HEAD ### Endpoint /api/query/{methodName} ### Response #### Success Response (200) - Indicates the query method resource is available. ``` -------------------------------- ### Set Page Size with URL Parameter Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/paging-and-sorting.adoc To change the default page size (20 entities) when accessing a collection, append the 'size' parameter to the URL. ```http http://localhost:8080/people/?size=5 ``` -------------------------------- ### Paged Response Link Example Source: https://github.com/spring-projects/spring-data-rest/wiki/Paging-and-Sorting A paged response includes links to navigate between pages. The 'rel' value indicates whether it's a 'next' or 'prev' link, and 'href' provides the URL for that page. ```json { "rel" : "people.next", "href" : "http://localhost:8080/people?page=2&limit=20" } ``` -------------------------------- ### Implement Custom Repository Event Handling with AbstractRepositoryEventListener Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Extend AbstractRepositoryEventListener to provide type-safe handling of repository events like beforeCreate, afterCreate, beforeSave, afterSave, beforeDelete, and afterDelete. Useful for pre/post-processing data or performing side effects. ```java import org.springframework.data.rest.core.event.AbstractRepositoryEventListener; import org.springframework.stereotype.Component; @Component public class BookEventListener extends AbstractRepositoryEventListener { @Override protected void onBeforeCreate(Book book) { // Normalize ISBN format book.setIsbn(book.getIsbn().replaceAll("-", "")); } @Override protected void onAfterCreate(Book book) { // Index in search engine searchService.index(book); } @Override protected void onBeforeSave(Book book) { // Validate before update validateIsbn(book.getIsbn()); } @Override protected void onAfterSave(Book book) { // Update search index searchService.reindex(book); } @Override protected void onBeforeDelete(Book book) { // Check if book can be deleted if (book.hasActiveLoans()) { throw new IllegalStateException("Cannot delete book with active loans"); } } @Override protected void onAfterDelete(Book book) { // Remove from search index searchService.remove(book.getId()); } @Override protected void onBeforeLinkSave(Book book, Object linked) { // Before adding author association } @Override protected void onAfterLinkDelete(Book book, Object linked) { // After removing author association } } ``` -------------------------------- ### Add a Family using curl Source: https://github.com/spring-projects/spring-data-rest/wiki/Example-API-usage-with-curl Use a POST request with JSON data to create a new 'Family' entity. The response includes a 'Location' header with the URL of the newly created resource. ```bash $ curl -X POST -v -d '{"surname" : "Doe"}' -H "Content-Type: application/json" http://localhost:8080/family ``` -------------------------------- ### Domain Type with Last Modified Date Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/etags-and-other-conditionals.adoc This domain type captures the last modification date using Spring Data Commons' @LastModifiedDate annotation. This allows for efficient conditional GET requests. ```java package example.mongodb; import org.springframework.data.annotation.LastModifiedDate; import java.util.Date; public class Receipt { @LastModifiedDate private Date lastModifiedDate; // other fields and methods } ``` -------------------------------- ### Handle Repository Events with Annotations in Spring Data REST Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Implement custom logic before or after CRUD operations using annotations like @HandleBeforeCreate, @HandleAfterCreate, etc. This example demonstrates validation and setting timestamps. ```java import org.springframework.data.rest.core.annotation.*; import org.springframework.stereotype.Component; // Annotation-based event handler @Component @RepositoryEventHandler public class PersonEventHandler { @HandleBeforeCreate public void handleBeforeCreate(Person person) { // Validate or modify before creation if (person.getFirstName() == null) { throw new IllegalArgumentException("First name is required"); } person.setCreatedAt(new Date()); } @HandleAfterCreate public void handleAfterCreate(Person person) { // Send notification, update cache, etc. System.out.println("Created person: " + person.getId()); } @HandleBeforeSave public void handleBeforeSave(Person person) { // Called before update operations person.setUpdatedAt(new Date()); } @HandleAfterSave public void handleAfterSave(Person person) { // Post-update processing } @HandleBeforeDelete public void handleBeforeDelete(Person person) { // Cleanup related data } @HandleAfterDelete public void handleAfterDelete(Person person) { // Post-deletion processing } // Link events for associations @HandleBeforeLinkSave public void handleBeforeLinkSave(Person person, Object linked) { // Before adding an association } @HandleAfterLinkDelete public void handleAfterLinkDelete(Person person, Object linked) { // After removing an association } } ``` -------------------------------- ### HAL Response for Second Page Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/paging-and-sorting.adoc The HAL response for the second page shows the current page number as 1 and includes both `prev` and `next` links for navigation. ```json { "_links" : { "self" : { "href" : "http://localhost:8080/persons{&sort,projection,page,size}", "templated" : true }, "next" : { "href" : "http://localhost:8080/persons?page=2&size=5{&sort,projection}", "templated" : true }, "prev" : { "href" : "http://localhost:8080/persons?page=0&size=5{&sort,projection}", "templated" : true } }, "_embedded" : { ... data ... }, "page" : { "size" : 5, "totalElements" : 50, "totalPages" : 10, "number" : 1 } } ``` -------------------------------- ### Create Person Entity Source: https://context7.com/spring-projects/spring-data-rest/llms.txt Create a new person entity using a POST request with JSON payload. The response includes the location of the created resource. ```bash curl -X POST http://localhost:8080/api/people \ -H "Content-Type: application/json" \ -d '{"firstName": "John", "lastName": "Doe"}' ``` ```bash curl -X POST http://localhost:8080/api/people \ -H "Content-Type: application/json" \ -d '{"firstName": "Jane", "lastName": "Doe"}' ``` -------------------------------- ### Search Resource - HEAD Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/repository-resources.adoc Returns whether the search resource is available. A 404 return code indicates no query method resources are available. ```APIDOC ## HEAD /api/search ### Description Returns whether the search resource is available. ### Method HEAD ### Endpoint /api/search ### Response #### Success Response (200) - Indicates the search resource is available. #### Error Response (404 Not Found) - Indicates no query method resources are available. ``` -------------------------------- ### Customizing Query Method Path with @RestResource Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/customizing/configuring-the-rest-url-path.adoc Use the @RestResource annotation on a query method to specify a custom path segment for its exposure under the 'search' resource. This example sets the path to "names". ```java @RepositoryRestResource(path = "people") interface PersonRepository extends CrudRepository { @RestResource(path = "names") List findByName(String name); } ``` -------------------------------- ### Implement ApplicationListener for Repository Events Source: https://github.com/spring-projects/spring-data-rest/blob/main/src/main/antora/modules/ROOT/pages/events.adoc Extend `AbstractRepositoryEventListener` to create a listener for repository events. Override specific methods like `onBeforeSave` or `onAfterDelete` to implement custom logic. Note that this approach does not distinguish between entity types by default. ```java public class BeforeSaveEventListener extends AbstractRepositoryEventListener { @Override public void onBeforeSave(Object entity) { ... logic to handle inspecting the entity before the Repository saves it } @Override public void onAfterDelete(Object entity) { ... send a message that this entity has been deleted } } ``` -------------------------------- ### Customizing Repository and Query Method Rels Source: https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path Both the repository and its query methods can have their 'rel' attributes customized using the @RestResource annotation. This example sets the repository rel to 'people' and the query method rel to 'names'. ```java @RestResource(path = "people", rel = "people") public interface PersonRepository extends CrudRepository { @RestResource(path = "names", rel = "names") public List findByName(String name); } ``` -------------------------------- ### Sort Results by Property with Direction Source: https://github.com/spring-projects/spring-data-rest/wiki/Paging-and-Sorting To sort results by a specific property, use the 'sort' URL parameter. Append ',asc' or ',desc' to specify the sort direction. This example sorts by 'name' in descending order. ```curl curl -v http://localhost:8080/people/search/nameStartsWith?name=K&sort=name,desc ```