Code Monkey home page Code Monkey logo

halboy's Introduction

halboy

Current Version

A Clojure library for all things hypermedia.

  • Create hypermedia resources
  • Marshal to and from JSON, or a map
  • Navigate JSON+HAL APIs

API

Resources

With Halboy you can create resources, and pull information from them.

(require '[halboy.resource :as hal])

(def my-resource
    (-> (hal/new-resource {:href "/orders/123"})
        (hal/add-link :creator {:href "/users/rob"})
        (hal/add-resource :discount (-> (hal/new-resource {:href "/discounts/1256"})
                                         (hal/add-property :discount-percentage 10)))
        (hal/add-resource :items [(-> (hal/new-resource {:href "/items/534"})
                                     (hal/add-property :price 25.48))])
        (hal/add-property :state :dispatching)))

(hal/get-link my-resource :self)
; { :href "/orders/123" }

(hal/get-href my-resource :creator)
; "/users/rob"

(hal/get-property my-resource :state)
; :dispatching

(-> (hal/get-resource my-resource :discount)
    (hal/get-property :discount-percentage))
; 10

(-> (hal/get-resource my-resource :items)
    (first)
    (hal/get-property :price))
; 25.48

Marshalling

You can also marshal your hal resources to and from maps, or JSON.

(require '[halboy.resource :as hal])
(require '[halboy.json :as haljson])

(def my-resource
    (-> (hal/new-resource {:href "/orders/123"})
        (hal/add-link :creator {:href "/users/rob"})
        (hal/add-resource :items (-> (hal/new-resource {:href "/items/534"})
                                     (hal/add-property :price 25.48)))
        (hal/add-property :state :dispatching)))

(haljson/resource->map my-resource)
; { :_links { :self { :href "/orders/123" },
;           :creator { :href "/users/rob" } },
;   :_embedded {:items { :_links { :self { :href "/items/534" } },
;                      :price 25.48 } },
;   :state :dispatching }

(haljson/resource->json my-resource)
; Formatted in these docs only.
;
; {
;   \"_links\": {
;     \"self\": {
;       \"href\": \"/orders/123\"
;     },
;     \"creator\": {
;       \"href\": \"/users/rob\"
;     }
;   },
;   \"_embedded\": {
;     \"items\": {
;       \"_links\": {
;         \"self\": {
;           \"href\": \"/items/534\"
;         }
;       },
;       \"price\": 25.48
;     }
;   },
;   \"state\": \"dispatching\"
; }

(-> (haljson/resource->json my-resource)
    (haljson/json->resource)
    (hal/get-href :self))
; "/orders/123"

Navigation

Provided you're calling a HAL+JSON API, you can discover the API and navigate through its links. When you've found what you want, you call navigator/resource and you get a plain old HAL resource, which you can inspect using any of the methods above.

(require '[halboy.resource :as hal])
(require '[halboy.navigator :as navigator])

; GET / - 200 OK
; {
;  "_links": {
;    "self": {
;      "href": "/"
;    },
;    "users": {
;      "href": "/users"
;    },
;    "user": {
;      "href": "/users/{id}",
;      "templated": true
;    }
;  }
;}

(def users-result
     (-> (navigator/discover "https://api.example.com/")
         (navigator/get :users))

(navigator/status users-result)
; 200

(navigator/location users-result)
; "https://api.example.com/users"

(-> (navigator/discover "https://api.example.com/")
    (navigator/get :user {:id "rob"})
    (navigator/location))
; "https://api.example.com/users/rob"

(def sue-result
     (-> (navigator/discover "https://api.example.com/")
         (navigator/post :users {:id "sue" :name "Sue" :title "Dev"}))

(navigator/location sue-result)
; "https://api.example.com/users/sue"

(-> (navigator/resource sue-result)
    (hal/get-property :title))
; "Dev"

Contributing

I'm happy to receive and go through feedback, bug reports, and pull requests.

If you need to contact me, my email is jimmy[at]jimmythompson.co.uk.

Development

To run the tests:

$ lein test

halboy's People

Contributors

jimmythompson avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.