Spring HATEOAS - Library to support implementing representations for hyper-text driven REST web services.

Overview

ga snapshot spring hateoas

icon?job=spring hateoas%2Fmaster&subject=master icon?job=spring hateoas%2F1.2.x&subject=1.2 icon?job=spring hateoas%2F1.1.x&subject=1.1 icon?job=spring hateoas%2F1.0.x&subject=1.0 icon?job=spring hateoas%2F0.25.x&subject=0.25

Spring HATEOAS

This project provides some APIs to ease creating REST representations that follow the HATEOAS principle when working with Spring and especially Spring MVC. The core problem it tries to address is link creation and representation assembly.

Working with Spring HATEOAS

Since all commits are headlined with its github issue, git will treat it as a comment. To get around this, apply the following configuration to your clone:

git config core.commentchar "/"

Making a release

  1. Create a new release (on the main branch).

    % ci/create-release.sh <release ticket without hash> <release version> <next snapshot version>
  2. With the release tagged, push the tagged version to the release branch.

    % git checkout -b release
    % git reset --hard <tag>
    % git push -f origin release
Note
You can chain the previous set of commands together using &&.

The pipeline will build and release the "release" branch. It will also build a new snapshot and stage it on artifactory. And if it’s a .RELEASE, the pipeline will push it out to Maven Central. To complete a release on Maven Central, you must login to the server shown in pom.xml, close, and release. This is a stop gap to guard against bad releases accidentally getting pushed out to Maven Central.

Running CI tasks locally

Since the pipeline uses Docker, it’s easy to:

  • Debug what went wrong on your local machine.

  • Test out a a tweak to your test.sh script before sending it out.

  • Experiment against a new image before submitting your pull request.

All of these use cases are great reasons to essentially run what Jenkins does on your local machine.

Important
To do this you must have Docker installed on your machine.
  1. docker run -it --mount type=bind,source="$(pwd)",target=/spring-hateoas-github adoptopenjdk/openjdk8:latest /bin/bash

    This will launch the Docker image and mount your source code at spring-hateoas-github.

  2. cd spring-hateoas-github

    Next, run the test.sh script from inside the container:

  3. PROFILE=none ci/test.sh

Since the container is binding to your source, you can make edits from your IDE and continue to run build jobs.

If you need to test the build.sh script, then do this:

  1. docker run -it --mount type=bind,source="$(pwd)",target=/spring-hateoas-github --mount type=bind,source="/tmp/spring-hateoas-artifactory",target=/spring-hateoas-artifactory adoptopenjdk/openjdk8:latest /bin/bash

    This will launch the Docker image and mount your source code at spring-hateoas-github and the temporary artifactory output directory at spring-hateoas-artifactory.

    Next, run the build.sh script from inside the container:

  2. ci/build.sh

Important
build.sh will attempt to push to Artifactory. If you don’t supply credentials, it will fail.
Note
Docker containers can eat up disk space fast! From time to time, run docker system prune to clean out old images.
Comments
  • @EnableHypermediaSupport is not compatible with Spring Boot's Jackson2ObjectMapperBuilder

    @EnableHypermediaSupport is not compatible with Spring Boot's Jackson2ObjectMapperBuilder

    I am trying to customize Jackson serialization for ISO dates. Per Spring Boot instructions, I created a @Bean of type Jackson2ObjectMapperBuilder:

        @Bean
        public Jackson2ObjectMapperBuilder objectMapperBuilder() {
            Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
            builder.featuresToDisable(
                    SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
                    DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
            return builder;
        }
    

    However, I find that these settings are not applied when using @EnableHypermediaSupport. When I remove the annotation, I see the effects of the Jackson serialization settings.

    resolution: duplicate 
    opened by pimlottc 49
  • Sample for embedding HAL Resources of different types with root resource

    Sample for embedding HAL Resources of different types with root resource

    Hi, Google is full of questions around how to create embedded HAL resources of different types inside the main root resource. I looked at the Resources Interface, but that can only be leveraged by same types to model collection of a particular type. I am currently using Spring-Hateoas to create a nested resource hierarchy and creating "_embedded" jsonproperty looks like a hack. Spring Data Rest has support for embedding entities, so it will be really helpful if you could please create a sample for embedding different type of single and collection of resources within a root resource.

    type: enhancement in: core in: mediatypes 
    opened by anywhereinfo 42
  • ResourceSupport.getId() too restrictive

    ResourceSupport.getId() too restrictive

    Having ResourceSupport.getId() method return Link is too restrictive IMO. It makes my representation unable to have id field and corresponding getId() method with different type. It seems a very common use case to assume in UI that the id field of resource would return actual id of the resource and not a link. Probably ResourceSupport could also be made generic where the id return type is passed by the class extending ResourceSupport.

    opened by deepakpol 40
  • Name embedded collections

    Name embedded collections

    The Resources type (and any derived types, ie PagedResource) should allow you to name the collection that will eventually be the embedded set. It's auto named now, but the api developer should really have control over this.

    opened by drdamour 38
  • BoundMethodParameter references static, default instance of ConversionService

    BoundMethodParameter references static, default instance of ConversionService

    Currently the BoundMethodParameter class references a static, default instance of ConversionService. This means that should a user add Converters to their ApplicationContext they will not be picked up and used. This should be changed such that a ConversionService specified in the ApplicationContext will be used, otherwise the default will be.

    type: enhancement 
    opened by nebhale 38
  • ResourceSupport.getId() shadows properties named

    ResourceSupport.getId() shadows properties named "id" on content objects

    because of the naming. because of a known bug (that concernes jsonUnwrap) in jackson it is not possible to create an "id" property on model objects that are wrapped into resources. the resourceSupport.getId will shadow the model property getId.

    you can successfuly serialize such resources but you can not deserialize them. jackson will simply ignore the "id" property because it is annotated with jsonignore on the resourcesupport class.

    the easy workaround is to rename the model property into something other than "id". but thats a bit annoying.

    resolution: wontfix 
    opened by Laures 36
  • Provide JSON API support

    Provide JSON API support

    I create this feature request after some discussions and thoughts that happen after the JSON API in a Java Web Application blog post and on the SPR-13570.

    JSON API is a specification for how a client should request that resources be fetched or modified, and how a server should respond to those requests. Clients built around JSON API are able to take advantage of its features around efficiently caching responses, sometimes eliminating network requests entirely. Why not use the HAL specification? is also worth to read.

    Ultimately, the goal of this feature is to provide support for the client-side Javascript JSON API libraries, like the most advanced one Ember Data.

    I am not a Spring HATEOAS expert, but my thoughts about that is that such support may be achieved by adding JSON API format support in addition to HAL, and providing standardized ResourceController/RelationshipController Spring MVC controller interfaces that may the the Spring couterpart of Katharsis ResourceRepository/RelationshipRepository. This last point seems quite important since JSON API is not just a format, and also defines standardized REST endpoints for dealing with CRUD and relationship operation. You can have a look to RESThub RestController for an example of such controller interface.

    I have not the knowledge to contribute that support alone, but I will be happy to contribute.

    type: enhancement specification in: mediatypes 
    opened by sdeleuze 35
  • x-forwarded-proto broken in Spring Boot 2.1.1

    x-forwarded-proto broken in Spring Boot 2.1.1

    For the following test:

    @Test
    fun `GET links uses proto headers`() {
         mvc.perform(get("/v1/").header("x-forwarded-proto", "https"))
                  .andExpect(status().isOk)
                  .andExpect(jsonPath("$._links.activate.href", startsWith("https")))
    }
    

    And the following implementation:

    private fun buildLinkForUser(currentUser: User) =  
    entityLinks.linkToCollectionResource(UserResource::class.java).withRel("activate")
    

    Or alternatively with controller links, e.g.:

    fun buildLinkForUser(): Link = linkTo(methodOn(UserController::class.java).activate())
                    .withRel("activate")
    

    I get the test passing in Spring Boot 2.0.7 and failing in Spring Boot 2.1.1 - because the link gets http instead of https.

    I checked Spring Hateoas in both boot releases and it remains 0.25.0. Obviously, this makes me think this issue doesn't belong here. However, I was hoping you could help me reassign it where it belongs?

    opened by CalamarBicefalo 34
  • Application does not start due to two bean instances of org.springframework.plugin.core.PluginRegistry (Follow-up)

    Application does not start due to two bean instances of org.springframework.plugin.core.PluginRegistry (Follow-up)

    As explained in the last comment of #966 , an application using spring-hateoas-1.0.0 does not start if the bean factory is setup in a way that the ParameterNameDiscoverer is null or an alternative implementation.

    The reason is that when autowiring of PluginRegistry into the bean _relProvider it finds two candidates and choosing one soley relies on the constructor argument name (same in EntityLinksConfigurationwhere the other instance of PluginRegistry is created.)

    This could be easily resolved by using @Qualifier annotations and named beans.

    resolution: invalid 
    opened by rainer198 32
  • Allow creation of UriTemplates when pointing to controller methods.

    Allow creation of UriTemplates when pointing to controller methods.

    Would be nice to have an easy way of return URL templates directly. For instance, suppose we have a method like

    @RequestMapping
    public HttpEntity<ListResource> list(
            @RequestParam(value = "query", required = false) String query,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "limit", defaultValue = "10") Integer limit) {
        // ...
    }
    

    I can reference an specific invocation with linkTo(methodOn(Controller.class).list("foo", 1, 20) but I think there is no easy way to reference a generic call without specifing the method parameters. Invoking with null results in a exception.

    I would like to get something like

    {
        rel: "list"
        href: "http://localhost:8080/myresource{?query,page,limit}"
    }
    

    Is that possible? Regards

    opened by Gotusso 29
  • HttpMessageConverters not prepended with HAL Message Converter

    HttpMessageConverters not prepended with HAL Message Converter

    Hi,

    On the startup of our application Spring instantiates certain processors like HttpEntityMethodProcessor and RequestResponseBodyMethodProcessor. These will be created with a reference to a list of HttpMessageConverters.

    The list instance is set in the abstract class AbstractMessageConverterMethodArgumentResolver#messageConverters. But because some of the processors get created before HypermediaSupportBeanDefinitionRegistrar#registerBeanDefinitions is called it occurs that the replacing of the HttpMessageConverters will not have the proper effect.

    I.e. HypermediaSupportBeanDefinitionRegistrar#registerBeanDefinitions does :

    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        ....
        if (JACKSON2_PRESENT) {
            ...
            BeanDefinitionBuilder builder = rootBeanDefinition(Jackson2ModuleRegisteringBeanPostProcessor.class);
            ....
        }
        ....
    }
    

    Jackson2ModuleRegisteringBeanPostProcessor#postProcessAfterInitialization does

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        ....
        if (bean instanceof RequestMappingHandlerAdapter) {
            RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean;
            adapter.setMessageConverters(potentiallyRegisterModule(adapter.getMessageConverters()));
        }
        ....
    }
    

    Jackson2ModuleRegisteringBeanPostProcessor#potentiallyRegisterModule does

    private List<HttpMessageConverter<?>> potentiallyRegisterModule(List<HttpMessageConverter<?>> converters) {
        ....
        List<HttpMessageConverter<?>> result = new ArrayList<HttpMessageConverter<?>>(converters.size());
        result.add(halConverter);
        result.addAll(converters);
        return result;
    }
    

    The problem seems to be here in potentiallyRegisterModule, it returns a new List of HttpMessageConverts while there are still objects looking at the original list.

    I tested this with : Spring 3.2.5 Spring Hateoas 0.9.0.BUILD-SNAPSHOT

    Many thx in advance for any input on this.

    M.

    opened by SirMaster 28
  • Interface Driven Controllers linkTo on path variables Spring MVC

    Interface Driven Controllers linkTo on path variables Spring MVC

    Hi, since Spring 5.1 "Controller parameter annotations get detected on interfaces as well: Allowing for complete mapping contracts in controller interfaces." I am trying to use the linkTo function on a class that implements an interface that has annotations on it for Path variables.

    Unfortunately, currently, this does not resolve the actual value of the path variable and instead uses a template. Copying the annotation down to the implementing class is currently a workaround but not pretty or DRY. Is this a bug that is known?

    I think #1081 documents this a little however never seems to have been looked at. I am now using spring boot 3.

    Thanks

    opened by M-Whitaker 0
  • Idea: Support for HAL/XML

    Idea: Support for HAL/XML

    Hello. I would like to know if you have plans for supporting HAL/XML in the future. Since I have seen some other people asking this same question in the past, but they did not receive a proper answer, I am reasking this question in case this has been forgotten.

    Best regards. 👍

    Source: How do you make Spring Hateoas return HAL/XML?

    opened by Mandroide 0
  • Can't perform PATCH update of an entity referring a child related element with its Hal URL in Native context

    Can't perform PATCH update of an entity referring a child related element with its Hal URL in Native context

    Hi Spring Hateoas team !

    I think I found a bug (I initially created an issue on spring-boot project, by I was told by mhalbritter this is most likely to be an issue for hateoas.

    I'm working with Spring-boot 3.0.0, that (through spring dependecy-management) pulls spring-hateoas 2.0.0 in my project. I work in a native context (builder paketobuildpacks/builder:tiny, 'BP_NATIVE_IMAGE': 'true' in my gradle bootBuildImage task)

    In a very simple context, when compiling with spring boot native, I can't perform a patch 'for example) update of my entity reffering a child entity with its url identifier.

    When I perform a PATH request with a body like this one:

    {
      "shouldBeChecked": true,
      "name": "Amical6",
      "parent": null,
      "authority": "https://myurl/api/authorities/e52cdfb6-6f3c-4552-8ea4-e1357b5d052c"
    }
    

    I get the following errors :

    in the web navigator (running the client app):

    {"cause":{"cause":null,"message":"Cannot construct instance of `org.[xxx].Authority` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('https://myurl/api/authorities/e52cdfb6-6f3c-4552-8ea4-e1357b5d052c')\n at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.[xxx].MyObject[\"authority\"])"},"message":"Could not read payload"}
    

    And, in my application logs :

    Failed to evaluate Jackson deserialization for type [[simple type, class org.springframework.data.rest.webmvc.PersistentEntityResource]]: java.lang.NullPointerException
    

    While, in the meantime, when run my project in a non native context (for example in my favourite IDE), I've got no problem at all.

    Please find below:

    • the Stack overflow discussion (https://stackoverflow.com/questions/74573299/how-to-deserialize-json-object-referring-related-data-using-hal-links-with-jacks?noredirect=1)
    • A reproducer project (how-to reproduce is described in the readme) (https://github.com/mathieupedreropro/spring-hal-jackson-graalvm).
    • the inital issue I submitted to spring boot project (https://github.com/spring-projects/spring-boot/issues/33468)

    Thanks a lot !

    opened by mathieupedreropro 0
  • RepresentationModelProcessor nullpointer having mandatory field in controller spring 2.7.4

    RepresentationModelProcessor nullpointer having mandatory field in controller spring 2.7.4

    Hello,

    I have a ResourceProcessor that's adding links to a resource:

    linkTo(methodOn(MyController.class) .findMyElements(file.getId(), null, null)) .withRel("filterFiles"))

    The controller looks like this:

    @RequestMapping(method = { POST, GET }, value = "/myFiles/{fileId}/filterFiles") public List<FileDto> findFilterFiles( @PathVariable("fileId") final Long fileId, @RequestParam(name = "fileType") final Long fileType, @RequestBody(required = false) final FileFilterDto filter)

    In Spring 2.6.4, it used to work. Now, I've tried upgrading to 2.7.4 and it does not work anymore. I've tracked the issue down and it seems like the required request param must not be null anymore.

    I'm getting a null pointer exception with text like this: Illegal character in query at index 93: http://localhost:8080/files/10013/filterFiles?fileType={fileType} with the index pointing to '=' of fileType={fileType} .

    Is it a bug? If yes - how can I fix it? Passing a constant number fixes the null-pointer exception:

    linkTo(methodOn(MyController.class) .findMyElements(file.getId(), 1L, null)) .withRel("filterFiles"))

    but it leads to incorrect code.

    opened by csigmanek 1
  • How Haetoas Conform add Links

    How Haetoas Conform add Links

    I want to add links to some related entities and collection, without all data in one response.

    Simple example of data Model

    Order Order->AddressFrom Order->PackageItems

    Which is the wright HAETOAS way to generate links or how to name entities in response. First problem, how to link address, double in entity name and links part or with another name?

    {
       "_embedded":{
          "orders":[
             {
                "id":"e312e342-c5f2-4a1b-8e59-8b36c7d906f3",
                "addressLinkFrom":{
                   "href":"http://localhost:8080/api/v1/addresses/21228740-fabb-4eb1-8a3f-855f49efb075"
                },
                "_links":{
                   "self":{
                      "href":"http://localhost:8080/api/v1/orders/edf77543-594f-4cf4-903d-80eefe4baa7d"
                   },
                   "addressFrom":{
                      "href":"http://localhost:8080/api/v1/addresses/60a096ef-29e1-4fef-a26a-e6e909a1f1ad"
                   }
                }
             }
          ]
       }
    }
    
    or
    
    {
       "_embedded":{
          "orders":[
             {
                "id":"e312e342-c5f2-4a1b-8e59-8b36c7d906f3",
                "addressFrom":{
                   "href":"http://localhost:8080/api/v1/addresses/21228740-fabb-4eb1-8a3f-855f49efb075"
                },
                "_links":{
                   "self":{
                      "href":"http://localhost:8080/api/v1/orders/edf77543-594f-4cf4-903d-80eefe4baa7d"
                   },
                   "addressFrom":{
                      "href":"http://localhost:8080/api/v1/addresses/60a096ef-29e1-4fef-a26a-e6e909a1f1ad"
                   }
                }
             }
          ]
       }
    }
    
    

    Second how to link collection to specific and not all entities of a endpoint. (Or name to packageItems)

    {
       "_embedded":{
          "orders":[
             {
                "id":"e312e342-c5f2-4a1b-8e59-8b36c7d906f3",
                "packageItemIds":[
                   {
                      "href":"http://localhost:8080/api/v1/packageitems/d79b3c7a-f3ae-4aff-9bd9-cc4fcbea7d24"
                   },
                   {
                      "href":"http://localhost:8080/api/v1/packageitems/21ca96e4-5198-4865-8738-23063e18df52"
                   }
                ],
                "_links":{
                   "self":{
                      "href":"http://localhost:8080/api/v1/orders/edf77543-594f-4cf4-903d-80eefe4baa7d"
                   }
                }
             }
          ]
       }
    }
    

    or

                "packageItemIds":[
                   {
                     "self:"{
    
                      "href":"http://localhost:8080/api/v1/packageitems/d79b3c7a-f3ae-4aff-9bd9-cc4fcbea7d24"
                   }
    }]
    
    

    Third how is the right format for (update, post), which I have to parse, like the address, where I'm sending the ID or like the packageItems, where I sending the link.

             {
                "id":"e312e342-c5f2-4a1b-8e59-8b36c7d906f3",
    "addressFrom":{
    "id":"12345"
    }
    
                "packageItems":[
                   {
                      "href":"http://localhost:8080/api/v1/packageitems/d79b3c7a-f3ae-4aff-9bd9-cc4fcbea7d24"
                   },
                   {
                      "href":"http://localhost:8080/api/v1/packageitems/21ca96e4-5198-4865-8738-23063e18df52"
                   }
                ],
                "_links":{
                   "self":{
                      "href":"http://localhost:8080/api/v1/orders/edf77543-594f-4cf4-903d-80eefe4baa7d"
                   }
                }
             }
     
    

    For your information, as frontend Client I'm using lagoshny / ngx-hateoas-client, when someone has their extra information beside the HAETOAS standard, how is the best way, please tell me.

    Thanks for your help.

    opened by MichaelKoch11 0
  • Limitations of nested embedded resources through private HalRepresentationModel

    Limitations of nested embedded resources through private HalRepresentationModel

    We have a REST service which is implement with SpringBoot and HATEOAS. The following method exists within the WebService

    @Override
    public ResponseEntity<?> getCar(String carId) {
            Car car = carService.findById(carId).orElseThrow(() -> {
                    throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Car not found!");
            });
                   
           // toDTO & HATEOAS Links
           CarItem carItem = carModelAssembler.toModel(car);
             
           HalModelBuilder builder = HalModelBuilder.halModelOf(carItem);
           builder.embed(garageModelAssembler.toModel(car.getGarage()), LinkRelation.of("garage"));
                
           return ResponseEntity.ok(builder.build());
    }
     
    

    The response looks like this (abbreviated):

    {
       "id":"xyu",
       "garageId":"096a07ea-3970-4968-9cd9-4756ae6a9cb1",
       "_embedded": {
           "garage":{
             "id":"abc",
             "location":"XY",
             "_links":{
                "self":{
                   "href":"https://localhost:8443/api/v1/garages/096a07ea-3970-4968-9cd9-4756ae6a9cb1"
                },
            }
         }
      },
      "_links": {
        "self": {
          "href":"https://localhost:8443/api/v1/cars/d589852f-0b3f-4025-86cb-2fa3b35a1339"
        }
      }
    }
    

    We would also like to output the embedded objects in our paged responses. We came up with the following as a solution:

    @Component
    public class CarModelAssembler implements RepresentationModelAssembler<Car, RepresentationModel<CarItem>> {
            private GarageModelAssembler garageModelAssembler;
            private CarMapper carMapper;
     
            public BuildingModelAssembler(CarMapper carMapper, GarageModelAssembler garageModelAssembler) {
                    this.carMapper = carMapper;
                    this.garageModelAssembler = garageModelAssembler;
            }
     
            @Override
            public RepresentationModel<CarItem> toModel(Car car) {
                    return toModel(car, true);
            }
           
            public RepresentationModel<CarItem> toModel(Car car, boolean embedded) {
                    CarItem carItem = locationMapper.CarToCarItem(car);
                    HalModelBuilder builder = HalModelBuilder.halModelOf(carItem);
                   
                    // add Links
                    builder.link(linkTo(methodOn(CarController.class).getBuilding(carItem.getId())).withSelfRel());
                    builder.link(linkTo(methodOn(GarageController.class).getGarage(carItem.getGarage.getId())).withRel("garage"));
                   
                    if(embedded) {
                            builder.embed(garageModelAssembler.toModel(car.getGarage(), false));
                    }
                   
                    return builder.<CarItem>build();
            }
    }
    

    The call in the controller is then as follows: CollectionModel carItems = pagedResourcesAssembler.toModel(pCars, carModelAssembler);

    The whole thing works in principle, but I don't like the fact that: a. - I have to pack another RepresentationModel (RepresentationModel) around my CarItem (extends RepresentationModel). b. - I still have to install the embedded switch in the assembler so that there are no infinite nestings c. - I have to inject the required assemblers for the embedded objects everywhere, which means that sooner or later I have to work with @Lazy

    Unfortunately, I cannot use the HalRepresentationModel directly because it is private

    I'm hoping someone here has a better idea.

    opened by R-o-la-n-d 0
Releases(2.0.0)
  • 2.0.0(Nov 16, 2022)

    • #1880 - Upgrade to Spring Plugin 3.0.
    • #1879 - Upgrade to Reactor 2022.0.0.
    • #1878 - Upgrade Slf4j to 2.0.3.
    • #1877 - Upgrade to Spring Framework 6.0.
    • #1876 - Upgrade Logback to 1.4.4.
    • #1875 - Upgrade to Jakarta Servlet API 6.0.
    • #1874 - Upgrade to Kotlin 1.7.21.
    • #1873 - Upgrade to Mockk 1.13.2.
    • #1863 - Upgrade to Jackson 2.14.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-RC2(Nov 3, 2022)

    • #1869 - Upgrade to Spring Framework 6.0 RC3.
    • #1867 - Extract domain types from controller methods returning (Entity|Collection)Model instances for reflection.
    • #1866 - Extract types for AOT reflection from RepresentationModelAssemblers.
    • #1865 - Upgrade to Jackson 2.14 RC3.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-RC1(Nov 3, 2022)

    • #1861 - Upgrade to Reactor 2022.0 RC1.
    • #1860 - Upgrade to Spring Plugin 3.0 RC1.
    • #1859 - Add build profile to monitor Jackson 2.14 development.
    • #1858 - Improve AOT metadata.
    • #1857 - Upgrade to Spring Framework 6.0 RC1.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-M6(Sep 15, 2022)

    • #1819 - Add build time initialization hint for native compilation for MediaTypes.
    • #1822 - Add required runtime hints for native compilation.
    • #1827 - Switch to Spring Asciidoctor backends for reference documentation.
    • #1828 - Upgrade to Reactor 2022.0.0 M6.
    • #1830 - DummyInvocationUtils's ThreadLocal cache causes classloader leak.
    • #1846 - Upgrade to Spring Plugin 3.0 M2.
    • #1847 - Upgrade to Spring Framework 6.0 M6.
    • #1848 - Upgrade to Mockk 1.12.7.
    • #1849 - Upgrade to JUnit 5.9.
    • #1850 - Upgrade to JSONPath 2.7.0.
    • #1851 - Upgrade to Jackson 2.13.4.
    • #1852 - Upgrade to JaCoCo 0.8.8.
    • #1853 - Upgrade to Logback 1.4.1.
    • #1854 - Upgrade to Artifactory Maven Plugin 3.4.0.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.2(Sep 15, 2022)

    • #1843 - Upgrade to Spring Framework 5.3.23.
    • #1842 - Upgrade to Lombok 1.18.24.
    • #1841 - Upgrade to Jackson 2.13.4.
    • #1840 - Upgrade to Logback 1.2.11.
    • #1839 - Upgrade to Slf4j 1.7.36.
    • #1829 - Upgrade to Reactor 2020.0.23.
    • #1820 - DummyInvocationUtils's ThreadLocal cache causes classloader leak.
    Source code(tar.gz)
    Source code(zip)
  • 1.4.5(Sep 15, 2022)

    • #1837 - Upgrade to Spring Framework 5.3.23.
    • #1836 - Upgrade to Lombok 1.8.24.
    • #1835 - Upgrade to Jackson 2.13.4.
    • #1834 - Upgrade to Logback 1.2.11.
    • #1833 - Upgrade to Slf4j 1.7.36.
    • #1832 - Upgrade to Reactor 2020.0.23.
    • #1831 - DummyInvocationUtils's ThreadLocal cache causes classloader leak.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-M5(Jul 22, 2022)

  • 2.0.0-M4(Jul 14, 2022)

    • #1813 - Upgrade to Spring Framework 6.0 M5.
    • #1812 - Upgrade to Slf4j 1.7.36.
    • #1811 - Upgrade to Lombok 1.18.24.
    • #1810 - Upgrade to AssertJ 3.23.1.
    • #1809 - Upgrade to Reactor 2022.0.0 M4.
    • #1808 - Upgrade to Kotlin 1.7.
    • #1800 - UriTemplate can't recognize variable names that contain a dot.
    • #1796 - Change signature of ReactiveRepresentationModelAssembler.
    • #1793 - Path segment capturing {*…} not correctly expanded.
    • #1790 - Upgrade to Reactor 2022.0.0 M2.
    • #1775 - Optimization around constructing UriTemplate with multiple template variables of the same type.
    • #1722 - LinkBuilderSupport.toUri() double-encodes request parameters.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.1(Jun 20, 2022)

    • #1801 - UriTemplate can't recognize variable names that contain a dot.
    • #1797 - Optimization around constructing UriTemplate with multiple template variables of the same type.
    • #1794 - Path segment capturing {*…} not correctly expanded.
    • #1791 - LinkBuilderSupport.toUri() double-encodes request parameters.
    Source code(tar.gz)
    Source code(zip)
  • 1.4.4(Jun 20, 2022)

    • #1802 - UriTemplate can't recognize variable names that contain a dot.
    • #1798 - Optimization around constructing UriTemplate with multiple template variables of the same type.
    • #1795 - Path segment capturing {*…} not correctly expanded.
    • #1792 - LinkBuilderSupport.toUri() double-encodes request parameters.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-M3(May 12, 2022)

    • #1788 - Upgrade to Reactor 2020.0.19.
    • #1787 - Upgrade to Spring Framework 6.0 M4.
    • #1776 - MultipartFile parameter must not be added as template variable.
    • #1764 - Performance improvements in TemplateVariable.essence().
    Source code(tar.gz)
    Source code(zip)
  • 1.5.0(May 12, 2022)

    • #1782 - Upgrade to Reactor 2020.0.19.
    • #1781 - Upgrade to Spring Framework 5.3.20.
    • #1779 - MultipartFile parameter must not be added as template variable.
    Source code(tar.gz)
    Source code(zip)
  • 1.4.3(May 12, 2022)

    • #1784 - Upgrade to Reactor 2020.0.19.
    • #1783 - Upgrade to Spring Framework 5.3.20.
    • #1780 - MultipartFile parameter must not be added as template variable.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.0-RC1(May 12, 2022)

    • #1772 - Upgrade to Jackson 2.13.2.1.
    • #1771 - Upgrade to Reactor 2020.0.18.
    • #1770 - Upgrade to Spring Framework 5.3.19.
    • #1765 - Performance improvements in TemplateVariable.essence().
    Source code(tar.gz)
    Source code(zip)
  • 1.4.2(May 12, 2022)

    • #1774 - Upgrade to Jackson 2.13.2.1.
    • #1769 - Upgrade to Reactor 2020.0.18.
    • #1768 - Upgrade to Spring 5.3.19.
    • #1766 - Performance improvements in TemplateVariable.essence().
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-M2(Feb 17, 2022)

  • 1.5.0-M2(Feb 17, 2022)

  • 2.0.0-M1(Jan 17, 2022)

    • #1752 - Upgrade to Spring Plugin 3.0 M1.
    • #1751 - Upgrade to Spring Framework 6.0 M2.
    • #1719 - Adapt to Framework's removal of DefaultUriTemplateHandler.
    • #1639 - Prepare 2.0 development.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.0-M1(Jan 14, 2022)

    • #1739 - Upgrade to Kotlin 1.6.10.
    • #1738 - Upgrade to Reactor 2020.0.15.
    • #1737 - Upgrade to Spring Framework 5.3.15.
    • #1729 - TypeBasedInputPayloadMetadata missing equals(…) and hashCode().
    • #1727 - UriTemplate throws exception for host variables.
    • #1701 - Potential memory leak in WebMvcLinkBuilder.
    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Jan 14, 2022)

    • #1746 - Upgrade to Jackson 2.13.1.
    • #1745 - Upgrade to Reactor 2020.0.15.
    • #1744 - Upgrade to Spring Framework 5.3.15.
    • #1731 - UriTemplate throws exception for host variables.
    • #1730 - TypeBasedInputPayloadMetadata missing equals(…) and hashCode().
    • #1723 - Potential memory leak in WebMvcLinkBuilder.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.7(Jan 14, 2022)

    • #1742 - Upgrade to Jackson 2.12.6.
    • #1741 - Upgrade to Reactor 2020.0.15.
    • #1740 - Upgrade to Spring Framework 5.3.15.
    • #1732 - TypeBasedInputPayloadMetadata missing equals(…) and hashCode().
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Nov 22, 2021)

    • #1716 - Upgrade to Spring Framework 5.3.13.
    • #1715 - Upgrade to Reactor 2020.0.13.
    • #1697 - Custom types not supported in HAL FORMS properties description.
    • #1696 - Adding request parameter template variables to a URI already containing one, produce invalid template.
    • #1688 - Use Links.collector() in JsonPathLinksDiscoverer.
    • #1687 - Fix Javadoc in LinkDiscoverer.findLinkWithRel(…).
    • #1686 - Error serializing EntityModel when content is an empty bean and the ObjectMapper is configured to not fail on those.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.6(Nov 22, 2021)

    • #1712 - Upgrade to Spring Framework 5.3.13.
    • #1711 - Upgrade to Reactor 2020.0.13.
    • #1699 - Custom types not supported in HAL FORMS properties description.
    • #1693 - Error serializing EntityModel when content is an empty bean and the ObjectMapper is configured to not fail on those.
    • #1691 - Use Links.collector() in JsonPathLinksDiscoverer.
    • #1689 - Fix Javadoc in LinkDiscoverer.findLinkWithRel(…).
    Source code(tar.gz)
    Source code(zip)
  • 1.2.11(Nov 22, 2021)

    • #1709 - Upgrade to Spring Framework 5.3.13.
    • #1708 - Upgrade to Reactor 2020.0.13.
    • #1694 - Error serializing EntityModel when content is an empty bean and the ObjectMapper is configured to not fail on those.
    • #1692 - Use Links.collector() in JsonPathLinksDiscoverer.
    • #1690 - Fix Javadoc in LinkDiscoverer.findLinkWithRel(…).
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0-RC1(Nov 22, 2021)

    • #1681 - Upgrade to Kotlin 1.5.31.
    • #1680 - Upgrade to Reactor 2020.0.12.
    • #1679 - Upgrade to Lombok 1.18.22.
    • #1678 - Upgrade to JUnit 5.8.1.
    • #1677 - Upgrade to Jackson 2.13.0.
    • #1676 - Upgrade to AssertJ 3.21.0.
    • #1662 - HAL FORMS target must only contain URLs.
    • #1659 - Fix sample of HalModelBuilder in documentation.
    • #1658 - Re-expose AnnotationMappingDiscoverer.
    • #1657 - Prevent IndexOutOfBoundException if no media type configurations registered.
    • #1652 - Imprecise definition of how parameters are handled in MethodLinkBuilderFactory.linkTo(…) methods.
    • #1648 - Remove deprecations.
    • #1647 - Upgrade to Spring Framework 5.3.11.
    • #1640 - Upgrade compatibility builds to JDK 17.
    • #1638 - DummyInvocationUtils.methodOn(…) fails for methods returning Object on JDK 17.
    • #1637 - Upgrade Lombok to 1.18.20 for JDK 17 support.
    • #1448 - Irritating log output when pointing to controller methods that return a Mono.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.5(Nov 22, 2021)

    • #1675 - Upgrade to Reactor 2020.0.12.
    • #1674 - Upgrade to Spring Framework 5.3.11.
    • #1673 - Upgrade to Lombok 1.18.22.
    • #1663 - Fix sample of HalModelBuilder in documentation.
    • #1661 - IndexOutOfBoundException if no media type configurations registered.
    • #1653 - Better exception in case of wrong parameter array length in MethodLinkBuilderFactory.linkTo(…) methods.
    • #1649 - Irritating log output when pointing to controller methods that return a Mono.
    • #1643 - Upgrade Lombok to 1.18.20 for JDK 17 support.
    • #1642 - Upgrade compatibility builds to JDK 17.
    • #1641 - DummyInvocationUtils.methodOn(…) fails for methods returning Object on JDK 17.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.10(Nov 22, 2021)

    • #1671 - Upgrade to Lombok 1.18.22.
    • #1670 - Upgrade to Mockk 1.10.6.
    • #1668 - Upgrade to Reactor 2020.0.12.
    • #1667 - Upgrade Maven Wrapper to 3.8.3.
    • #1666 - Upgrade to Spring Framework 5.3.11.
    • #1664 - Fix sample of HalModelBuilder in documentation.
    • #1650 - Irritating log output when pointing to controller methods that return a Mono.
    • #1646 - DummyInvocationUtils.methodOn(…) fails for methods returning Object on JDK 17.
    • #1645 - Upgrade Lombok to 1.18.20 for JDK 17 support.
    • #1644 - Upgrade compatibility builds to JDK 17.
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0-M3(Sep 16, 2021)

    • #1634 - Upgrade to AssertJ 3.20.2.
    • #1633 - Upgrade to EvoInflector 1.3.
    • #1632 - Upgrade to Logback 1.2.6.
    • #1631 - Upgrade to JaCoCo 0.8.7.
    • #1630 - Upgrade to Jackson 2.12.5.
    • #1629 - Upgrade to JUnit 5.8.
    • #1628 - Upgrade to Slf4j 1.7.32.
    • #1627 - Upgrade to Mockk 1.12.0.
    • #1626 - Upgrade to Kotlin 1.5.30 and Coroutines 1.5.3.
    • #1625 - Upgrade to Reactor 2020.0.11.
    • #1624 - Upgrade to Spring Framework 5.3.10.
    • #1609 - Avoid superfluous object creation in Link.valueOf(…).
    • #1608 - HAL-FORMS affordance method is in lowercase instead of uppercase.
    • #1607 - Remove deprecations in Affordances.
    • #1602 - Wrong nullability declarations for properties of Link.
    • #1599 -@JsonIdentityInfo not rendering correctly since Spring HATEOAS 1.1.2.
    • #1598 - Custom converter is not used for enum list query parameter.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.4(Sep 16, 2021)

    • #1622 - Upgrade to Jackson 2.12.5.
    • #1621 - Upgrade to Reactor 2020.0.11.
    • #1620 - Upgrade to Slf4j 1.7.32.
    • #1619 - Upgrade to Kotlin 1.4.32.
    • #1618 - Upgrade to Spring Framework 5.3.10.
    • #1610 - Avoid superfluous object creation in Link.valueOf(…).
    • #1605 - Wrong nullability declarations for properties of Link.
    • #1603 - @JsonIdentityInfo not rendering correctly since Spring HATEOAS 1.1.2.
    • #1600 - Receiving duplicate key when bean property accessors collide.
    • #1589 - WebMvcLinkBuilder.linkTo(Method, Object[]) does not append request parameters properly.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.9(Sep 16, 2021)

    • #1617 - Upgrade to Jackson 2.11.4.
    • #1616 - Upgrade to Reactor 2020.0.11.
    • #1615 - Upgrade to Slf4j 1.7.32.
    • #1614 - Upgrade to Kotlin 1.4.32.
    • #1613 - Upgrade to Spring Framework 5.3.10.
    • #1611 - Avoid superfluous object creation in Link.valueOf(…).
    • #1606 - Wrong nullability declarations for properties of Link.
    • #1604 - @JsonIdentityInfo not rendering correctly since Spring HATEOAS 1.1.2.
    • #1601 - Receiving duplicate key when bean property accessors collide.
    Source code(tar.gz)
    Source code(zip)
A damn simple library for building production-ready RESTful web services.

Dropwizard Dropwizard is a sneaky way of making fast Java web applications. It's a little bit of opinionated glue code which bangs together a set of l

Dropwizard 8.3k Jan 5, 2023
Rest.li is a REST+JSON framework for building robust, scalable service architectures using dynamic discovery and simple asynchronous APIs.

Rest.li is an open source REST framework for building robust, scalable RESTful architectures using type-safe bindings and asynchronous, non-blocking I

LinkedIn 2.3k Dec 29, 2022
Microserver is a Java 8 native, zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. Supporting pure Microservice or Micro-monolith styles.

Microserver A convenient modular engine for Microservices. Microserver plugins offer seamless integration with Spring (core), Jersey, Guava, Tomcat, G

AOL 936 Dec 19, 2022
Leading REST API framework for Java

Restlet Framework The leading REST API framework for Java Thanks to Restlet Framework's powerful routing and filtering capabilities, unified client an

Restlet Framework 633 Dec 18, 2022
Examples and server integrations for generating the Swagger API Specification, which enables easy access to your REST API

Swagger Core NOTE: If you're looking for Swagger Core 1.5.X and OpenAPI 2.0, please refer to 1.5 branch. NOTE: Since version 2.1.7 Swagger Core suppor

Swagger 7.1k Jan 5, 2023
Simple JSP Servlets REST api.

Simple JSP Servlets REST api.

MisterFunny01 3 May 9, 2021
RestAhead - compile time generated REST client

RestAhead - compile time generated REST client This project draws inspiration from projects such as Retrofit and Feign, but with a twist: your service

Žan Skamljič 13 Dec 24, 2022
JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.

Greetings, Java Hipster! Full documentation and information is available on our website at https://www.jhipster.tech/ Please read our guidelines befor

JHipster 20.2k Jan 5, 2023
Rapidoid - Extremely Fast, Simple and Powerful Java Web Framework and HTTP Server!

Rapidoid - Simple. Powerful. Secure. Fast! Rapidoid is an extremely fast HTTP server and modern Java web framework / application container, with a str

null 1.6k Dec 30, 2022
Library for OpenAPI 3 with spring-boot

Full documentation Acknowledgements springdoc-openapi is made possible thanks to all of its contributors. Introduction The springdoc-openapi Java libr

springdoc-openapi 2.3k Jan 5, 2023
🪖 A library for counting queries for Spring Data JPA application

?? Query-Counter Query-Counter is a library for counting queries for Spring Data JPA application, currently supporting Hibernate only. It aims to help

Jinhong 3 Dec 12, 2021
Spring GraphQL demo application

Spring Projects GraphQL API This repository is a demo application for introducing the Spring GraphQL project. This is currently based on Spring Boot a

Brian Clozel 4 Aug 24, 2022
Nano-library which provides the ability to define typesafe (!) configuration templates for applications.

Configur8 Nano-library which provides the ability to define typesafe (!) Configuration templates for applications. Concept: A Configuration is a set o

David Denton 11 Oct 3, 2022
Spring HATEOAS - Library to support implementing representations for hyper-text driven REST web services.

Spring HATEOAS This project provides some APIs to ease creating REST representations that follow the HATEOAS principle when working with Spring and es

Spring 920 Mar 8, 2021
Spring Boot JdbcTemplate example with SQL Server: CRUD Rest API using Spring Data JDBC, Spring Web MVC

Spring Boot JdbcTemplate example with SQL Server: Build CRUD Rest API Build a Spring Boot CRUD Rest API example that uses Spring Data Jdbc to make CRU

null 7 Dec 20, 2022
HATEOAS with HAL for Java. Create hypermedia APIs by easily serializing your Java models into HAL JSON.

hate HATEOAS with HAL for Java. Create hypermedia APIs by easily serializing your Java models into HAL JSON. More info in the wiki. Install with Maven

null 20 Oct 5, 2022
Nullify for null representations and assertions of objects

Nullify Nullify for null representations and assertions of objects. Philosophy A semantic emptiness is a key concept used to indicate the absence of a

Hyesung Lee 2 Jan 20, 2022