{"id":1803,"date":"2024-12-08T19:47:16","date_gmt":"2024-12-08T16:17:16","guid":{"rendered":"https:\/\/mshaeri.com\/blog\/?p=1803"},"modified":"2025-07-14T09:49:39","modified_gmt":"2025-07-14T06:19:39","slug":"spring-rest-framework-a-project-inspired-by-django-rest-framework","status":"publish","type":"post","link":"https:\/\/mshaeri.com\/blog\/spring-rest-framework-a-project-inspired-by-django-rest-framework\/","title":{"rendered":"Spring Rest Framework (SRF) A Project Inspired by Django Rest Framework"},"content":{"rendered":"\n<p>For years, I\u2019ve been deeply immersed in the Django ecosystem, developing APIs and building applications using Django and Django Rest Framework. <strong>DRF<\/strong> has always worked as magician for me, significantly reducing boilerplate code while offering robust flexibility. On the flip side, I\u2019ve also spent a fair share of time working with Spring and Spring Boot. While Spring is fantastic in many ways, I noticed the gap when it came to a DRF-like experience. The absence of a framework that could remove boilerplate codes, streamline API development in the Spring world, and provide a similar level of flexibility was something that always bugged me. So, I decided put some effort to tackle this gap. In my spare time over the past 7 months, I\u2019ve been working on creating a framework like DRF, designed and tailored for the Spring ecosystem. And that\u2019s how <strong>Spring Rest Framework<\/strong> was born.<\/p>\n\n\n\n<p>The goal was to build a framework that would reduce boilerplate code, simplify the <strong>filtering<\/strong>, <strong>serialization<\/strong>, and <strong>validation <\/strong>in the regular web APIs development to expose CRUD operation for models, and bring some of the fantastic features of <strong>DRF<\/strong> to the Spring world. There\u2019s still a lot of work to be done. The framework is far from perfect, and there are numerous features and improvements that need to be added. I\u2019d love to invite anyone who\u2019s interested to contribute to this project. Whether you\u2019re a seasoned developer or someone eager to get their hands dirty with open-source, your help would be greatly appreciated. There\u2019s plenty of room for enhancement, and I welcome any bug reports, feature requests, or contributions you might have.<\/p>\n\n\n\n<p>I\u2019ll write about the technical aspects of Spring Rest Framework in another blog post. But to introduce the simplicity of working with this tool, here is the snippet code where you can expose a listing endpoint for city model with variety of filtering parameter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">@RequestMapping(\"\/cities\")\n@RestController\n@Tag(name = \"City\")\npublic class CityController extends ListController&lt;City, Long, CityRepository&gt; {\n      public CityController(CityRepository repository) {\n            super(repository);\n      }\n\n      @Override\n      protected Class&lt;?&gt; getDTO() {\n            return CityDto.class;\n      }\n      \n      @Override\n      protected FilterSet configFilterSet() {\n      return FilterSet.builder()\n            .addFilter(\"name\", FilterOperation.CONTAINS, FieldType.STRING, \"Check containing a name\")\n            .addFilter(\"continent\", \"country__continent__name\", FilterOperation.CONTAINS, FieldType.STRING, \"Check containing a continent name\")\n            .addFilter(\"number_of_people\", \"population\", FilterOperation.BETWEEN, FieldType.INTEGER, \"Retrieves cities with population between provided population range\")\n            .build();\n      }\n}  <\/code><\/pre>\n\n\n\n<p>In the example the <code><strong>continent<\/strong><\/code> (mapped to <code><strong>country__continent__name<\/strong><\/code>) Checks for a substring in related model <code><strong>continent<\/strong><\/code>&#8216;s <strong><code>name<\/code><\/strong>. <code><strong>name<\/strong><\/code> filter parameter checks if the name contains a given string. And <code><strong>number_of_people<\/strong><\/code> (mapped to <code><strong>population<\/strong><\/code> field of <strong>City<\/strong> model) filters cities within a specific population range in specific continent.<\/p>\n\n\n\n<p>In this example the presence of filter parameters are optional, so the endpoint can be called like this to query the database records:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">curl -X GET \"http:\/\/localhost:8080\/cities?continent=Europe&amp;number_of_people_from=140000&amp;number_of_people_to=250000\"<\/code><\/pre>\n\n\n\n<p>If you liked it, please give the project a star on <a href=\"https:\/\/github.com\/nikanique\/spring-rest-framework\" target=\"_blank\" rel=\"noreferrer noopener\">Spring Rest Framework<\/a> Github repository. Here are some helpful resources to get you started:<\/p>\n\n\n\n<ol>\n<li><strong><a href=\"https:\/\/spring-rest-framework-tutorial.readthedocs.io\/en\/latest\/\">Official Spring Rest Framework Documentation<\/a><\/strong><\/li>\n\n\n\n<li><strong><a href=\"https:\/\/medium.com\/@mosymosy262\/learn-spring-rest-framework-srf-with-example-e49bacc3b777\">Learn Spring REST Framework (SRF) With Example<\/a><\/strong><\/li>\n\n\n\n<li><strong><a href=\"https:\/\/medium.com\/@mosymosy262\/advanced-spring-rest-framework-srf-tutorial-with-example-2bcb033de333\">Advanced Spring REST Framework (SRF) Tutorial with Example<\/a>.<\/strong><\/li>\n\n\n\n<li><strong><a href=\"https:\/\/dev.to\/birddevelper\/validation-in-spring-rest-framework-5e04\">Validation in Spring REST Framework<\/a><\/strong><br><\/li>\n<\/ol>\n\n\n\n<p>Happy coding! \ud83d\ude80<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For years, I\u2019ve been deeply immersed in the Django ecosystem, developing APIs and building applications using Django and Django Rest Framework. DRF has always worked &hellip; <\/p>\n","protected":false},"author":1,"featured_media":1904,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,69,70],"tags":[97,272,218,258,259,264,267,262,274,9,118,265,63,71,276,261,260,112,266],"_links":{"self":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/1803"}],"collection":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/comments?post=1803"}],"version-history":[{"count":5,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/1803\/revisions"}],"predecessor-version":[{"id":1983,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/1803\/revisions\/1983"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/media\/1904"}],"wp:attachment":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/media?parent=1803"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/categories?post=1803"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/tags?post=1803"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}