Skip to content

Instantly share code, notes, and snippets.

@nikitaeverywhere
Last active January 9, 2016 15:46
Show Gist options
  • Save nikitaeverywhere/6b991d42ab7835f9d52f to your computer and use it in GitHub Desktop.
Save nikitaeverywhere/6b991d42ab7835f9d52f to your computer and use it in GitHub Desktop.
Implementation-very-basic-draft
<Routes>
<!-- Self-documenting links variant: allow <Route> tag to nest additional info -->
<Route Url="/posts" Method="GET" Call="ShowPosts">
<!-- One of many variants, most applicable for Caché XData scheme on my opinion -->
<!-- Nested <Link>s tell what we can do with the current element -->
<Link rel="add" method="POST" href="/posts"/>
<Link rel="next" method="POST" href="/posts/:page"/>
<!-- Nested <LinkGroup>s tell what we can do with the content on the page -->
<LinkGroup name="post">
<Link rel="edit" method="PUT" href="/post/:id"/>
<Link rel="delete" method="DELETE" href="/post/:id"/>
</LinkGroup>
<!-- OR, if we already have an entity (route) separate description, just import it -->
<!-- This will include all links from another <Route> in this XData -->
<LinkGroup route="/post/:id"/>
</Route>
<!-- OPTIONS shows the extended API of POST/PUT/DELETE calls, so in case we have -->
<!-- F.E. <link rel="add" .../> we can ask route for it's options -->
<Route Url="/posts" Method="OPTIONS" Call="postsOptions"/>
<!-- Tiny OPTIONS response example: {
"POST": {
"description": "Create a new post.",
"parameters": {
"title": {
"type": "string",
"description": "A post title.",
required: true
},
"text": {
"type": "string",
"description": "A post body.",
required: true
}
}
}
} -->
<Route Url="/post/:id" Method="GET" Call="ShowPost">
<Link rel="edit" method="PUT" href="/post/:id"/>
<Link rel="delete" method="DELETE" href="/post/:id"/>
</Route>
<!-- "OPTIONS /post/:id": {
"PUT": { ...the same as in POST /posts, except of descriptions, etc... },
"DELETE": { "description": "Remove the post." }
} -->
</Routes>
ClassMethod ShowPosts(postId As %Numeric) As %Status
{
// Then, the last point left is to let programmers inject this links where needed. Let say
// we have methods like ..InjectLinks(object) and ..InjectLinkGroup(object, "groupName").
// During compile time, Caché will collect all links from UrlMap scheme and these methods
// will know exactly which <Route> to associate with this COS Method.
// To make thinks easy to demonstrate, let say we have gethered this data for the client:
set data = { // Caché 2016 JSON objects
"title": "A list of post made by users",
"posts": [
{
"title": "First post",
"text": "This is the first post.",
"author": "Anonymous",
"date": "1/1/2015"
},
{
"title": "Second post",
"text": "This is the next post.",
"author": "User2",
"date": "1/2/2015"
}
// , ...
]
}
// Then, to include all links before sending data to the client (write data.$toJSON())
do ..InjectLinks(.data) // any form of method, this just demonstrates a "method call"
// 1. Determines type of data object - JSON "object"
// 2. Adds property f.e. "_links" which is an array of all links present in <Route>
// Then for each child element (can be raplaced with cycle)
do ..InjectLinkGroup(.data.posts."0", "post")
do ..InjectLinkGroup(.data.posts."1", "post")
// ...
// Respond
do %response.SetHeader("Content-Type", "text/json")
write test.$toJSON()
quit $$$OK
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment