packages feed

json-api 0.1.0.2 → 0.1.0.3

raw patch · 3 files changed

+136/−5 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Network.JSONApi.Document: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Network.JSONApi.Document.ErrorDocument a b)
- Network.JSONApi.Document: instance (GHC.Classes.Eq a, GHC.Classes.Eq b, GHC.Classes.Eq c) => GHC.Classes.Eq (Network.JSONApi.Document.Document a b c)
- Network.JSONApi.Document: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Network.JSONApi.Document.ErrorDocument a b)
- Network.JSONApi.Document: instance (GHC.Show.Show a, GHC.Show.Show b, GHC.Show.Show c) => GHC.Show.Show (Network.JSONApi.Document.Document a b c)
- Network.JSONApi.ResourceObject: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Network.JSONApi.ResourceObject.ResourceObject a b)
- Network.JSONApi.ResourceObject: instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Network.JSONApi.ResourceObject.ResourceObject a b)
- Network.JSONApi.ResourceObject: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Network.JSONApi.ResourceObject.ResourceObject a b)
+ Network.JSONApi.Document: instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Network.JSONApi.Document.ErrorDocument a b)
+ Network.JSONApi.Document: instance (GHC.Classes.Eq c, GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Network.JSONApi.Document.Document a b c)
+ Network.JSONApi.Document: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Network.JSONApi.Document.ErrorDocument a b)
+ Network.JSONApi.Document: instance (GHC.Show.Show c, GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Network.JSONApi.Document.Document a b c)
+ Network.JSONApi.ResourceObject: instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Network.JSONApi.ResourceObject.ResourceObject a b)
+ Network.JSONApi.ResourceObject: instance (GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Network.JSONApi.ResourceObject.ResourceObject a b)
+ Network.JSONApi.ResourceObject: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Network.JSONApi.ResourceObject.ResourceObject a b)

Files

README.md view
@@ -3,14 +3,120 @@ ## Haskell Implementation of the JSON-API specification  ++#### Motivation++From the specification itself:++> If you’ve ever argued with your team about the way your JSON responses should+> be formatted, JSON API can be your anti-bikeshedding tool.+> +> By following shared conventions, you can increase productivity, take advantage+> of generalized tooling, and focus on what matters: your application.+> +> Clients built around JSON API are able to take advantage of its features around+> efficiently caching responses, sometimes eliminating network requests entirely.++All in all, API discoverability and other [HATEOAS](https://spring.io/understanding/HATEOAS)+principles make JSON-API an attractive resource serialization option.+++ #### The specification  Find the specification [here](http://jsonapi.org/)  + #### Example usage -There is an [example project](https://github.com/toddmohney/json-api/example) illustrating how the library can be used.+Let's start with an example User record:++```Haskell+data User = User+  { userId        :: Int+  , userFirstName :: String+  , userLastName  :: String+  } deriving (Eq, Show)++$(deriveJSON defaultOptions ''User)+```++From this, we can use the `json-api` package to produce a payload conformant+to the [JSON-API specification](http://jsonapi.org/) like so:++```Haskell+-- Builds the Document which will be serialized as our+-- web server's response payload+mkDocument :: User -> Links -> Document User Text Int+mkDocument usr links =+  Document+    (Singleton $ toResourceObject usr)+    (Just links)+    Nothing++-- Helper function to convert a User into a resource object+-- This could be our canonical serialization function for a User in any+-- response payload+toResourceObject :: User -> ResourceObject User Text+toResourceObject user =+  ResourceObject resourceId resourceType user resourceLinks resourceMetaData+  where+    resourceId       = ResourceId . pack . show . userId $ user+    resourceType     = ResourceType "User"+    resourceLinks    = Just $ userLinks user+    resourceMetaData = Nothing++-- helper function to build links for a User resource+userLinks :: User -> Links+userLinks user = toLinks [ ("self", selfLink) ]+  where+    selfLink = toURL selfPath+    selfPath = "/users/" <> (show $ userId user)+```++When delivered as a response from a web server, for example, we get a payload+that looks like this:++```JSON+{+  "data":{+    "attributes":{+      "userFirstName":"Isaac",+      "userLastName":"Newton",+      "userId":1+    },+    "id":"1",+    "meta":null,+    "type":"User",+    "links":{+      "self":"/users/1"+    }+  },+  "meta":null,+  "links":{+    "self":"/users/1"+  }+}+```++Neat! We can see that if we would like the full User data for the User with+ID=1, we can query `/users/1`. Discoverability!++We can also see from the top-level `links` data that this particular payload originated+from `/users/1`.++This is a very simple example to provide an introduction to the basic idea+behind JSON-API and how to use this library. Check out [these examples](http://jsonapi.org/examples/)+for more robust representations of resourceful payloads. Here, you'll start to+see the more comprehensive benefits of a discoverable API.++++#### Example Project++There is an [example project](https://github.com/toddmohney/json-api/tree/master/example) illustrating how the library can be used in the context of a web server.+   #### Hackage
example/README.md view
@@ -1,8 +1,33 @@ +#### Running the example +There's a `stack.yaml` file in this directory, so you can run and build this+example project in a familiar manner.++```bash+# pull your GHC deps+stack setup++# build the project+stack build++# run the webserver+stack exec example-exe+```++At this point you should have a webserver running at `http://localhost:8080`+You'll find available endpoints at the following urls:+- [http://localhost:8080/users](http://localhost:8080/users) - responds with a list of User resources+- [http://localhost:8080/users/1](http://localhost:8080/users/1) - responds with a singleton resource+- [http://localhost:8080/users/2](http://localhost:8080/users/2) - responds with a singleton resource+- [http://localhost:8080/users/3](http://localhost:8080/users/3) - responds with a 404 and error payload++++ ## List Resource Example -```json+```JSON GET /users  {@@ -46,7 +71,7 @@  ## Singleton Resource Example -```json+```JSON GET /users/1  {@@ -73,7 +98,7 @@  ## Error Example -```json+```JSON GET /users/3  {
json-api.cabal view
@@ -1,5 +1,5 @@ name:                json-api-version:             0.1.0.2+version:             0.1.0.3 homepage:            https://github.com/toddmohney/json-api bug-reports:         https://github.com/toddmohney/json-api/issues license:             MIT