Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/krainboltgreene/hsdk.js
A HATEOAS HTTP client that generates SDKs based on a specific endpoint
https://github.com/krainboltgreene/hsdk.js
hateoas jsonapi mediatype sdk
Last synced: 9 days ago
JSON representation
A HATEOAS HTTP client that generates SDKs based on a specific endpoint
- Host: GitHub
- URL: https://github.com/krainboltgreene/hsdk.js
- Owner: krainboltgreene
- License: isc
- Created: 2016-09-18T10:12:59.000Z (over 8 years ago)
- Default Branch: core
- Last Pushed: 2022-12-07T17:35:56.000Z (about 2 years ago)
- Last Synced: 2024-10-31T02:03:05.455Z (about 2 months ago)
- Topics: hateoas, jsonapi, mediatype, sdk
- Language: JavaScript
- Homepage:
- Size: 754 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# hsdk
hsdk stands for HATEOAS Software Development Kit. This library reads from a specified 'application metadata' endpoint and generates an HTTP HATEOAS API client.
![Version][BADGE_VERSION]
![Tests][BADGE_TRAVIS]
![Stability][BADGE_STABILITY]Example at play: https://esnextb.in/?gist=1ddc4e3e62196c8b9542b87a6141dff4
## using
First you need to define your core sdk and in this example we'll our jsonapi.org specification-compliant endpoint:
``` javascript
import hsdk from "hsdk"
import axios from "axios"const sdk = hsdk({
home: {
url: "https://hsdkjs.getsandbox.com/v1/resources",
headers: {
Accept: "application/vnd.api+json",
},
},
// You tell us how to make the request
http: ({url, method, payload}) => axios({
method,
url,
data: payload,
responseType: "JSON",
}),
// You tell us how to get to the JSON:API data
receive: (body) => body.data,
})
```The `sdk` constant above is a `Promise` based on a request/response to/from the home resource.
Now we can start making requests to our api, discovered πmagicallyπ:
``` javascript
sdk
.then((client) => client.accounts.v1.list())
.then((response) => console.log({message: "List", payload: response.data}))
```That will `log` a list of accounts.
``` javascript
sdk
.then((client) => client.accounts.v1.show({id: "1"}))
.then((response) => console.log({message: "Show", payload: response.data}))
```This will `log` a single account, with the `id` of `1`
``` javascript
sdk
.then((client) => {
return client.accounts.v1.update({
id: "1",
payload: {
data: {
id: "1",
type: "accounts",
attributes: {
age: 29
}
}
}
})
})
.then((response) => console.log({message: "Update", payload: response.data}))
```In `POST`, `PATCH`, or `PUT` requests (mutations) `hsdk` expects a `payload` value that it uses in the body. This `update` request will update the age of `accounts/1` to `29`.
hsdk doesn't care what kind of API you have, only that it is discoverable via `jsonapi-home`.
## jsonapi-home
Much like [json-home](https://mnot.github.io/I-D/json-home/), a fantastic spec by @mnot, jsonapi-home is an attempt to allow clients to build themselves.
Using the example above, we need a HTTP server running at `http://hsdkjs.getsandbox.com` that responds to `GET /v1/resources` requests.
Here is a sample CURL-based request (an example of what hsdk does under the hood):
``` bash
curl -X "GET" "http://hsdkjs.getsandbox.com/v1/resources" \
-H "Accept: application/vnd.api+json"
```Each resource MUST have the following properties:
- intent: The human name for this result, example: `list`, `show`, `create`, `destroy`, `update`
- namespace: The groupings this resource is under, can be anything
- version: The version of the endpoint, if no version you SHOULD use `latest`
- description: A short description for the resource
- method: The HTTP verb used
- href: A RFC 6570 URL template that the client can use directly
- mediatype: The preferred mediatype for this endpointThat response will look like this:
``` http
HTTP/1.1 200 OK
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
Date: Mon, 28 Nov 2016 19:50:32 GMT{
"links": {
"self": "https://hsdkjs.getsandbox.com/v1/resources",
"next": "https://hsdkjs.getsandbox.com/v1/resources?page[offset]=2",
"last": "https://hsdkjs.getsandbox.com/v1/resources?page[offset]=10"
},
"data": [
{
"id": "accounts-v1-list",
"type": "resources",
"attributes": {
"intent": "list",
"namespace": "accounts",
"version": "v1",
"description": "List accounts.",
"method": "GET",
"href": "https://hsdkjs.getsandbox.com/v1/accounts","mediatype": "application/vnd.api+json"
},
"links": {
"self": "https://hsdkjs.getsandbox.com/v1/resources/accounts-v1-list"
}
},
{
"id": "accounts-v1-show",
"type": "resources",
"attributes": {
"intent": "show",
"namespace": "accounts",
"version": "v1",
"description": "Show an individual account.",
"method": "GET",
"href": "https://hsdkjs.getsandbox.com/v1/accounts/{id}",
"allowed": [
["fields"]
],
"mediatype": "application/vnd.api+json"
},
"links": {
"self": "https://hsdkjs.getsandbox.com/v1/resources/accounts-v1-show"
}
},
{
"id": "accounts-v1-update",
"type": "resources",
"attributes": {
"intent": "update",
"namespace": "accounts",
"version": "v1",
"description": "Update an individual account.",
"method": "PATCH",
"href": "https://hsdkjs.getsandbox.com/v1/accounts/{id}",
"mediatype": "application/vnd.api+json"
},
"links": {
"self": "https://hsdkjs.getsandbox.com/v1/resources/accounts-v1-update"
}
}
]
}
```[BADGE_TRAVIS]: https://img.shields.io/travis/krainboltgreene/hsdk.js.svg?maxAge=2592000&style=flat-square
[BADGE_VERSION]: https://img.shields.io/npm/v/hsdk.svg?maxAge=2592000&style=flat-square
[BADGE_STABILITY]: https://img.shields.io/badge/stability-strong-green.svg?maxAge=2592000&style=flat-square