Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/linktosriram/clojure-spring-guide
Guidelines for using Clojure with Spring Framework
https://github.com/linktosriram/clojure-spring-guide
annotations clojure clojure-spring-guide java spring spring-boot spring-framework
Last synced: about 1 month ago
JSON representation
Guidelines for using Clojure with Spring Framework
- Host: GitHub
- URL: https://github.com/linktosriram/clojure-spring-guide
- Owner: linktosriram
- Created: 2017-11-18T08:35:13.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2017-11-18T10:18:25.000Z (almost 7 years ago)
- Last Synced: 2024-09-29T00:05:28.677Z (about 2 months ago)
- Topics: annotations, clojure, clojure-spring-guide, java, spring, spring-boot, spring-framework
- Homepage: https://linktosriram.github.io/clojure-spring-guide/
- Size: 2.93 KB
- Stars: 10
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# clojure-spring-guide
Guidelines for using Clojure with Spring Framework[Clojure Style Guide](https://goo.gl/WWfjB)
# Controllers
* Use [@RestController](https://goo.gl/DpiwnS)
* Use [@GetMapping](https://goo.gl/Y1tX55), [@PostMapping](https://goo.gl/BsajaA) family of annotations over traditional [@RequestMapping](https://goo.gl/naenPG) ones
* Consume and Produce [MediaType.APPLICATION_JSON_UTF8_VALUE](https://goo.gl/US1rUY)
* When returning clojure data structures out of controllers, use [cheshire](https://goo.gl/TCNat)
```clojure
(ns ...
(:require [cheshire.core :as json]))
```and then return using
```clojure
(json/generate-string {:a 1 :b 2})
```* When using annotations like [@PathVariable](https://goo.gl/b5XdMB), [@RequestParam](https://goo.gl/nm7ZiD) etc., specify the `value` attribute as the debugging information is not available. The value attribute can be dash-case.
Otherwise the following error will occur: `Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.`* We cannot require another namespace or import a class in `(ns :gen-class )`. The code emitted by ns macro calls `:gen-class` before calling any of the `:require` or `:import`.
Thus the required namespace/class or not compiled when `:gen-class` is called. We can use fully qualified names to solve this, but that would be ugly.
A Better solution is to call `(gen-class ...)` after `(ns ...)`* Method arguments types and return types still need to be fully qualified (except java.lang.*)
* Method names should be camelCase instead of dash-case due to Java restrictions
* If you prefer, you can return [CompletableFuture](https://goo.gl/QQ6uv2) from the controller method to be asynchronous with the following macro
```clojure
(ns ...
(:import (java.util.concurrent CompletableFuture)
(java.util.function Supplier)))
(defmacro async
"Wraps the given `body` inside a CompletableFuture."
[& body]
`(CompletableFuture/supplyAsync
(reify
Supplier
~(list 'get '[this] (cons 'do body)))))
```and then use it like
```clojure
(async
(println "Async Controller method")
(+ 3 5))
```## Complete Example
```clojure
(ns com.clojurespring.controller
(:require [cheshire.core :as json])
(:import (org.springframework.web.bind.annotation RestController GetMapping PathVariable)))(gen-class
:name ^{RestController {}} com.clojurespring.SampleController
:methods [[^{GetMapping {:value ["/hello"]
:produces ["application/json;charset=UTF-8"}}
hello [^{PathVariable {:value "name"}} String] java.util.concurrent.Future]])(defn -hello
[this name]
(async
(println "Inside async controller...")
(json/generate-string {:a 1
:message (str "Hello " name " from Clojure controller"))))
```
### Request
```bash
curl -X GET -H "Accept: application/json;charset=UTF-8" "http://server.name/hello/rich"
```### Response
```json
{
"a": 1,
"message": "Hello rich from Clojure controller"
}
```# Contributing
Nothing written in this guide is set in stone. It's my desire to work together with everyone interested in Clojure coding style, so that we could ultimately create a resource that will be beneficial to the entire Clojure community.
Feel free to open tickets or send pull requests with improvements. Thanks in advance for your help!