mikekelly / hal-browser Goto Github PK
View Code? Open in Web Editor NEWAn API browser for the hal+json media type
License: MIT License
An API browser for the hal+json media type
License: MIT License
Hi I am invoking my service like http://localhost:8080/foos?page=1&size=1 from HAL browser which give me an output like
{
"_links" : {
"first" : {
"href" : "http://localhost:8080/foos?page=0&size=1"
},
"prev" : {
"href" : "http://localhost:8080/foos?page=0&size=1"
},
"self" : {
"href" : "http://localhost:8080/foos"
},
"next" : {
"href" : "http://localhost:8080/foos?page=2&size=1"
},
"last" : {
"href" : "http://localhost:8080/foos?page=81&size=1"
}
},
"_embedded" : {
"hf:foos" : [ {
"name" : "comsi",
"_links" : {
"self" : {
"href" : "http://localhost:8080/foos/319001"
},
, "hf:foo" : {
"href" : "http://localhost:8080/foos/8445"
} ,
"curies" : [{"href": "/alps/{rel}",
"name":"hf",
"templated": true}
]
}
} ]
},
"page" : {
"size" : 1,
"totalElements" : 82,
"totalPages" : 82,
"number" : 1
}
}
the same does nto render and gives me an error
Uncaught Error: URNs do not have any generally defined hierarchical components in console
can anyone let me know what I am doing wrong as my api follows hal .The same works fine without curie namespaces in the embedded section seems to be a bug with the Uri.js
UPDATE
@olivergierke curies are coming but inside the _embedded resource as u have also said that seems to cause the issue.Have updated the spring data ticket https://jira.spring.io/browse/DATAREST-626 with the response
Hi,
While looking at the HAL browser here http://haltalk.herokuapp.com/explorer/browser.html I've noticed that after clicking the "docs" icon for the "ht:users" relation, the upper right "Inspector" box did not display correctly. Further investigation revealed that the issue was in the relative height of the ".documentation iframe" style definition.
.documentation iframe { width: 100%; height: 100%; }
For the reference, the Mozilla Developer Network specifies for the "height" attribute of the "iframe" element: "Indicates the height of the frame (HTML5) in CSS pixels, or (HTML 4.01) in pixels or as a percentage."
Also, as soon as I changed the value of "100%" to for example "400px", the "Inspector" box was immediately displayed correctly.
Regards,
Mladen.
when displaying a CURIE results it'd be nice if there was a way to view it as HTML in addition to the raw body.
When first opening the browser, it uses the entryPoint as defined in the browser HTML. However, the only way to return to this is to manually delete the query params. The obvious choice to return to the entry point is the "Go to root URI" link at the top, but this goes to /, instead of the entry point.
Hi mikekelly,
Thank you for your job. I am looking at your source code and try to port it into my app.
I am experienced with backbone JS and jquery, but the way we use to build app with it is slitghly different and I struggle bringing all the logic together. Probably because of my unexperience with HAL and your app.
Is anyone interested working on a port to react ?
The example on haltalk.herokuapp.com currently results in a 500 Internal Server Error: http://haltalk.herokuapp.com/explorer/browser.html#/users
I noticed that the HAL browser fails to render data if the curies 'section' is not present.
I think that a document without the curies section is still valid HAL since the formal HAL specification shows examples of documents without it.
In this case, the embedded and inspector sections are not shown at all.
An example follows:
This renders fine (also if _links.curies is an empty array):
{
"_type": "COLLECTION",
"_returned": 3,
"_links": {
"self": {
"href": "/test/albums?hal=c"
},
"curies": [
{
"href": "http://restheart.org/curies/1.0/{rel}.html",
"templated": true,
"name": "rh"
}
]
},
"_embedded": {
"rh:doc": [
{
"_links": {
"self": {
"href": "/test/albums/Three Imaginary Boys"
}
},
"_type": "DOCUMENT",
"_id": "Three Imaginary Boys",
"year": 1979,
"_etag": {
"$oid": "55f1601ec2e65448b566d18f"
}
},
{
"_links": {
"self": {
"href": "/test/albums/Seventeen Seconds"
}
},
"_type": "DOCUMENT",
"_id": "Seventeen Seconds",
"year": 1980,
"_etag": {
"$oid": "55f16023c2e65448b566d190"
}
},
{
"_links": {
"self": {
"href": "/test/albums/Disintegration"
}
},
"_type": "DOCUMENT",
"_id": "Disintegration",
"year": 1989,
"_etag": {
"$oid": "55f16015c2e65448b566d18e"
}
}
]
}
}
This doesn't: the embedded and inspector sections are not rendered! (note that the curies property is missing):
{
"_returned": 3,
"_type": "COLLECTION",
"_links": {
"self": {
"href": "/test/albums?hal=c"
}
},
"_embedded": {
"rh:doc": [
{
"_etag": {
"$oid": "55f1601ec2e65448b566d18f"
},
"_id": "Three Imaginary Boys",
"_links": {
"self": {
"href": "/test/albums/Three Imaginary Boys"
}
},
"_type": "DOCUMENT",
"year": 1979
},
{
"_etag": {
"$oid": "55f16023c2e65448b566d190"
},
"_id": "Seventeen Seconds",
"_links": {
"self": {
"href": "/test/albums/Seventeen Seconds"
}
},
"_type": "DOCUMENT",
"year": 1980
},
{
"_etag": {
"$oid": "55f16015c2e65448b566d18e"
},
"_id": "Disintegration",
"_links": {
"self": {
"href": "/test/albums/Disintegration"
}
},
"_type": "DOCUMENT",
"year": 1989
}
]
}
}
For reference, this is a Spring Data REST project.
The curie
doc is linked to, in this case, http://localhost:8080/alps/customers
.
Visiting that link directly leads to very valid ALPS data. However clicking the 'doc' link which opens the 'Inspector' view in the HAL browser shows no data at all.
Is this an issue or am I misusing the curie links?
This UI is a good starting point for an administration GUI.
For context, see http://stackoverflow.com/questions/34867014/javascript-crud-admin-for-spring-data-hateoas-backend
Title says it all.
Spring-HATEOAS is supporting HAL OOTB and it also has support for webjars as it's built on Spring MVC. Wrapping up the hal-browser into a webjar would be a great way to deploy it side by side with any Spring-HATEOAS implementation.
All that would need to happen is for someone to make releases on github for each significant milestone and leave it for all eternity (a small commitment). They don't even have to be major version numbers. 0.1.0 is fine...but they should follow semantic versioning.
I'm happy to put together the webjar package and submit it if a release is published on GH.
When requesting HAL talk with "Accept: application/json" everything works fine:
$ curl -D - -H "accept: application/json" http://haltalk.herokuapp.com/
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
{"_links":{"self":{"href":"/"},"curies": [...]
But with "Accept: application/hal+json" it doesn't:
$ curl -D - -H "accept: application/hal+json" http://haltalk.herokuapp.com/
HTTP/1.1 406 Not Acceptable
Content-Type: text/html; charset=utf-8
This came as a surprise to me. Maybe I'm missing something here? The HAL spec states "A HAL Document uses the format described in [RFC4627] and has the media type "application/hal+json". The example directly below that statement reads
GET /orders/523 HTTP/1.1
Host: example.org
Accept: application/hal+json
HTTP/1.1 200 OK
Content-Type: application/hal+json
That's why I would have expected the HAL talk example to behave the same, that is
Might be related to #22.
Would you consider a PR to support _links
(and perhaps also just links
) as a list of objects with rel
keys, in addition to the default HAL format of _links
as an object with keys representing rel
? An example of this occurs in this Spring article: https://spring.io/understanding/HATEOAS.
Shouldn't the Content-Type
be application/vnd.hal+json
instead of application/json
?
That would be great to have some collor and/or collapse like a JSONView plugin.
https://github.com/jamiew/jsonview-chrome/blob/master/jsonview.js
According to this ticket, this CVE is contained in the jQuery version used by HAL browser. Would you mind upgrading to a recent version that has this CVE fixed?
Clicking on a link like "next" typically results in a page that's identical in layout to the previous page. Nothing appears to change. Blink and you'll miss the change in the content of the Response Body etc.
I suggest a simple slight 'dimming' of the Response Headers and Response Body divs when a request is made, and un-dimming on completion.
A spinner would be a bonus. I'd suggest placing it just after the Response Headers title.
When performing non-get request repeatedly, the request breaks after the second request. The first two request work perfectly and on the third request, the URL for Non-GET(orange-self-link) is changed to NON-GET:///api/v1/person
and on submitting it, the Response Headers come out as:
0 [Exception... "" nsresult: "0x805e0006 ()" location: "JS frame :: https://vikesh/api/hal/vendor/js/jquery-1.10.2.min.js :: .send :: line 6" data: no]
It also stops working after the first request, if the page has been refreshed after a Non-get request i.e. page with URL https://vikesh/api/hal/browser.html#NON-GET:/api/v1/person
Finding one attribute among many is difficult when their not sorted.
Sorting also helps being attributes with the same prefix close together so the values are easy to compare.
@mikekelly Spring Data REST is using this project (via webjars) as a plugin, so anybody that builds a HAL-based service can easily serve up a HAL Browser front end with next to no effort.
A bonus feature Spring Data REST comes with is ALPS metadata which includes the properties for every resource. A feature I have wanted to add for some time is to use this metadata and make the HAL Browser's POST form more sophisticated by listing each property by name with separate fields, instead of a raw body field where the user must type in all the fields in JSON, and include the right names.
I am tinkering with a fork of the app to craft some extension point where someone could drop in extra JavaScript to fetch this extra metadata, but I'm finding it tricky to do so. I didn't know if you were interested in working on such an extension point for this project, or if you are too busy with other projects.
/cc @olivergierke
Create a test harness:
If anyone wants to help flesh out the various features and scenarios that would be most welcome! :)
If you open the NON-GET dialog and press submit, you get a URL of the form: http://haltalk.herokuapp.com/explorer/browser.html#NON-GET:/
If you modify the URL to include javascript for example, it turns out that the contents are displayed in the users' browser. Theoretically, this makes it possible to perform various actions, including stealing cookies etc.
An example to see the problem described above is going to this link on the demo-app of the HAL-browser:
http://haltalk.herokuapp.com/explorer/browser.html#NON-GET:/">'<script>alert("hi")</script>
Currently only the first level "_embedded" resources are handled properly. Even if a resource has nested "_embedded" resources then HAL browser renders only the first level.
Example:
{ "_links": { "self": { "href": "http://example.com/book/123/" }, "authors": { "href": "http://example.com/book/123/authors/" } }, "_embedded": { "authors": [ { "_links": { "self": { "href": "http://example.com/author/a/" }, "topBooks": { "href": "http://example.com/author/a/topbooks/" } }, "_embedded": { "topBooks": [ { "_links": { "self": { "href": "http://example.com/book/234/" } }, "name": "Author A's most popular book" }, { "_links": { "self": { "href": "http://example.com/book/235/" } }, "name": "Author A's 2nd most popular book" } ] } } ] } }
Hi, do you have any plans on turning hal-browser into a npm module or similar? It would be nice to be able to include it easily into other projects.
Would you mind if I take a look at this?
My app uses Oauth2. As a poor-man's workaround for testing I made the endpoint /api/browser/**
available to all. In the HAL Browser I've set the Custom Request Header to Authorization:bearer {token}
. Browsing the network calls in Chrome shows that the Authorization header is sent for GET requests, but not for NON-GET requests. This makes authorization for my endpoints fail for any NON-GET requests.
It's hard to navigate through the browser history when all the titles say "The HAL Browser"!
The 'title' attribute of the 'self' _link provides a natural title for the page, let's use it.
Rather than use the hal browser from the root directory I would prefer to point it to a remote service, e.g. localhost:8080
how can I do this?
HAL browser ignores second level _embedded properties in this example:
{
"abc":0,
"_links":{
"self":{
"href":"/link/1"
}
},
"_embedded":{
"level1":{
"def":1,
"_links":{
"self":{
"href":"/link/2"
}
},
"_embedded":{
"level2":{
"xyz":2,
"_links":{
"self":{
"href":"/link/3"
}
}
}
}
}
}
}
While trying the current branch of hal browser, I'm noticing CORS errors when going across site.
XMLHttpRequest cannot load http://foo.bar.baz/api/v1/. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://haltalk.herokuapp.com' is therefore not allowed access.
This works with an older version of hal-browser.
I notice issue #58 "Allow credentials for CORS requests" which seems to set the allowCredentials option in the hal browser client.
If the server responds with an error (eg status 500) the hal-browser doesn't report that to the user in any way.
It would be nice to have Links in Properties view to be clickable
<div class="resource"><div class="properties">
<h2>Properties</h2>
<pre>{
"links": [
{
"rel": "customer",
"href": "http://localhost:8080/rest/customer{?page,size,sort}"
},
{
"rel": "profile",
"href": "http://localhost:8080/rest/profile"
}
]
}</pre>
</div><div class="links">
<h2>Links</h2>
<table class="table">
<thead>
<tr>
<th>rel</th>
<th>title</th>
<th>name / index</th>
<th>docs</th>
<th>GET</th>
<th>NON-GET</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div></div>
Using hal-browser in my spring application to validate rest resources.
Now we implemented spring security using oAuth2 to protect all the resources.
Any one implemented authentication on top of hal-browser?
Assume we have a response like this:
{ "_links": {
"self": {
"href": "โฆ/orders{?page,size,sort}",
"template": true
}
}
Following that link should open up a dialog to enter values for the template variables and correctly expand the template.
It's surprising to click on a /resource{/id}
link and find the box that pops up contains
{ "foo": "bar" }
It would be helpful if the "foo" could at least be "id" from parsing the template. Even more helpful to present the user with something like this:
{
"id": ""
}
ideally with text box already given the focus and the cursor placed between the value quotes - but I don't know how tricky that would be.
uritemplate-js is the (Level 4) implementation for JS recommended here. See also this note comparing implementations.
When using the provided URL for the heroku app [1] I get the error:
"Application Error
An error occurred in the application and your page could not be served. Please try again in a few moments.
If you are the application owner, check your logs for details."
Convert the project into a bower component.
Hello folks,
I was trying to use this package along with another couple of our things and I have noticed that npm
did not include the two files browser.html
and login.html
in the deployed version.
I then came here and noticed that they are excluded by .gitignore
and unfortunately npm
does consider that when deploying.
So what I wanted to ask really is whether we could remove the line from .gitignore
or (more likely) there is a super valid reason not to do so ๐.
Thanks for this package @mikekelly, it is super useful!
Attempting to use
http://haltalk.herokuapp.com/explorer/browser.html
doesn't work.
If I just use GET /users, I get an internal server error.
Attempting to POST /users to create a new user leads to a 404.
If the server returns a header like this
Link: <h1>test</h1>
the html is not escaped.
It is both a security risk and annoying from a functionality standpoint because link headers take the following form :
Link:<http://some.api//v1/images/5217>; rel="canonical"
And these will now not show up in the response headers section
Getting Chrome error:
Uncaught Error: URNs do not have any generally defined hierarchical components
hal.js:27 var norm = uri.absoluteTo(cur);
When retrieving my API entry point:
{
"motd": "Welcome to the API Endpoint!",
"_links": {
"osdi:people": {
"href": "http://demo.osdi.io/api/v1/people",
"title": "The collection of people in the system"
},
.....
}
This makes it hard to use once there are more than a few links.
Sorting by rel then title, or title then rel, would be fine by me.
Even better would be to use a jquery table sorting plugin and let the user alter the default sort.
Giving special treatment to next and prev links to keep them at the top, at least in the default sort, might be useful to aid rapid paging.
When manually testing an API, it can be useful to change pre-loaded users to test different functionalities. For instance, testing whether only an "admin" can create an object, where a generic "user" cannot.
It would be really nice if the browser could support non-json resources, for example images, pdf or plain html. Perhaps it is possible to detect the media type of a resource and display it directly in a iframe when it is not json.
Hi, I'm playing with string boot and the HAL browser but I'm getting 405 every time I click on 'Non Get' icon.
I'm new with this tool and I'm not sure what I'm missing. I have an existing REST service created with Spring using @RestController, my endpoint is:
POST http://localhost:8080/api/v1/invoice/report/request
and I have that endpoint registered on the Hal Browser at http://localhost:8080/. This is the what I see on the screen:
{ "_links": { "invoicing:request": { "href": "http://localhost:8080/api/v1/invoice/report/request" }, "profile": { "href": "http://localhost:8080/profile" } } }
However, on the left side (NON-GET column) I'm unable to see the popup dialog to Make a Request, I'm not sure what I'm doing wrong.
Thanks
Note. Something I noticed is that if my endpoint is GET, then I do see the popup.
target url changed to: /
browser.js:55 target url changed to: /api/v1
URI.min.js:71 Uncaught Error: URNs do not have any generally defined hierarchical componentse.absoluteTo @ URI.min.js:71HAL.normalizeUrl @ hal.js:27(anonymous function) @ VM756:46_.each..forEach @ underscore.js:87(anonymous function) @ VM756:4.template.template @ underscore.js:1165HAL.Views.Links.Backbone.View.extend.render @ links.js:52HAL.Views.Resource.Backbone.View.extend.render @ resource.js:29(anonymous function) @ resource.js:8triggerEvents @ backbone.js:96Backbone.Events.trigger @ backbone.js:181$.ajax.success @ client.js:17x.Callbacks.c @ jquery-1.10.2.min.js:4x.Callbacks.p.fireWith @ jquery-1.10.2.min.js:4k @ jquery-1.10.2.min.js:6x.ajaxTransport.send.r @ jquery-1.10.2.min.js:6
browser.js:55 target url changed to: http://demo.osdi.io/api/v1
browser.html:1 XMLHttpRequest cannot load http://demo.osdi.io/api/v1. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://joshco.local.host:3000' is therefore not allowed access.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.