Giter Site home page Giter Site logo

hal-browser's Introduction

HAL-browser

An API browser for the hal+json media type

Example Usage

Here is an example of a hal+json API using the browser:

About HAL

HAL is a format based on json that establishes conventions for representing links. For example:

{
    "_links": {
        "self": { "href": "/orders" },
        "next": { "href": "/orders?page=2" }
    }
}

More detail about HAL can be found at http://stateless.co/hal_specification.html.

Customizing the POST form

By default, the HAL Browser can’t assume there is any metadata. When you click on the non-GET request button (to create a new resource), the user must enter the JSON document to submit. If your service includes metadata you can access, it’s possible to plugin a custom view that makes use of it.

  1. Define your custom view.

    Here is an example that leverages Spring Data REST’s JSON Schema metadata found at /{entity}/schema.

    var CustomPostForm = Backbone.View.extend({
    	initialize: function (opts) {
    		this.href = opts.href.split('{')[0];
    		this.vent = opts.vent;
    		_.bindAll(this, 'createNewResource');
    	},
    
    	events: {
    		'submit form': 'createNewResource'
    	},
    
    	className: 'modal fade',
    
    	createNewResource: function (e) {
    		e.preventDefault();
    
    		var self = this;
    
    		var data = {}
    		Object.keys(this.schema.properties).forEach(function(property) {
    			if (!("format" in self.schema.properties[property])) {
    				data[property] = self.$('input[name=' + property + ']').val();
    			}
    		});
    
    		var opts = {
    			url: this.$('.url').val(),
    			headers: HAL.parseHeaders(this.$('.headers').val()),
    			method: this.$('.method').val(),
    			data: JSON.stringify(data)
    		};
    
    		var request = HAL.client.request(opts);
    		request.done(function (response) {
    			self.vent.trigger('response', {resource: response, jqxhr: jqxhr});
    		}).fail(function (response) {
    			self.vent.trigger('fail-response', {jqxhr: jqxhr});
    		}).always(function () {
    			self.vent.trigger('response-headers', {jqxhr: jqxhr});
    			window.location.hash = 'NON-GET:' + opts.url;
    		});
    
    		this.$el.modal('hide');
    	},
    
    	render: function (opts) {
    		var headers = HAL.client.getHeaders();
    		var headersString = '';
    
    		_.each(headers, function (value, name) {
    			headersString += name + ': ' + value + '\n';
    		});
    
    		var request = HAL.client.request({
    			url: this.href + '/schema',
    			method: 'GET'
    		});
    
    		var self = this;
    		request.done(function (schema) {
    			self.schema = schema;
    			self.$el.html(self.template({
    			    href: self.href,
    			    schema: self.schema,
    			    user_defined_headers: headersString}));
    			self.$el.modal();
    		});
    
    		return this;
    	},
    	template: _.template($('#dynamic-request-template').html())
    });
  2. Register it by assigning to HAL.customPostForm

    HAL.customPostForm = CustomPostForm;
  3. Load your custom JavaScript component and define your custom HTML template.

    <script id="dynamic-request-template" type="text/template">
    <div class="modal-header">
      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
      <h3>Make a non-GET request</h3>
    </div>
    
    <form class="non-safe" action="<%= href %>">
      <div class="modal-body">
        <p>Target URI</p>
        <input name="url" type="text" class="url" value="<%= href %>" />
        <p>Method:</p>
        <input name="method" type="text" class="method" value="POST" />
        <p>Headers:</p>
        <textarea name="headers" class="headers" style="height: 100px">
        Content-Type: application/json
        <%= user_defined_headers %>
        </textarea>
      </div>
      <% _.each(schema.properties, function(value, name) { %>
        <% if (!("format" in value)) { %>
          <input type="text" placeholder="<%= name %>" name="<%= name %>" />
        <% } %>
      <% }); %>
      <div class="modal-footer">
        <button type="submit" class="btn btn-primary">Make Request</button>
      </div>
    </form>
    </script>
Note
To load a custom JavaScript module AND a custom HTML template, you will probably need to create a customized version of browser.html.
Note
The HAL Browser uses a global HAL object, so there is no need to deal with JavaScript packages.

Usage Instructions

All you should need to do is copy the files into your webroot. It is OK to put it in a subdirectory; it does not need to be in the root.

All the JS and CSS dependencies come included in the vendor directory.

TODO

  • Provide feedback to user when there are issues with response (missing self link, wrong media type identifier)

  • Give 'self' and 'curies' links special treatment

hal-browser's People

Contributors

alexdutton avatar andresf avatar bethesque avatar billyyarosh avatar cdent avatar col avatar dracoblue avatar enrique-ramirez avatar gregturn avatar ismasan avatar joshco avatar linclark avatar linkaraj avatar lukestokes avatar martinbooth avatar mikekelly avatar mtiller avatar plexus avatar sbrauer avatar smizell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hal-browser's Issues

Sort attribute keys in the formatted JSON

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.

Acceptance tests

Create a test harness:

  • Ruby?!
  • mock API
  • cucumber and phantomjs
  • TravisCI

If anyone wants to help flesh out the various features and scenarios that would be most welcome! :)

Custom Request Headers not sent for NON-GET requests

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.

Support view of non-json resources

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.

Convert to bower component

Convert the project into a bower component.

  • compile javascripts into one file
  • add dependencies via bower (e.g. uri-template, bootstrap, etc)
  • submit to bower index

Third consecutive non-get request doesn't work

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

Doesn't report server errors

If the server responds with an error (eg status 500) the hal-browser doesn't report that to the user in any way.

Cross site scripting issue

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

screen shot 2014-06-18 at 21 11 36

Cross Site Scripting issue with NON-GET dialog

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>

Curie link to ALPS data not rendering

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?

Add support for multiple levels of embedded Resource Objects

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"
                  }
               }
            }
         }
      }
   }
}

Offer as webjar for simple Spring-HATEOAS (and Play & etc.) integration

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.

CORS issue in recent versions

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.

The 'Links' section isn't sorted

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.

Support for nested "_embedded" items

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" } ] } } ] } }

_embedded resource with curie namespace not rendering in HAl browser ,gives error in uri.min.js

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

CURIE links as embedded HTML

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.

iframe attribute "height" specified in percentage is invalid in html 5

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.

"Go to root" link should go to entryPoint, not '/'

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.

Provide visual feedback when a request is in-progress

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.

Use the URI template fields to pre-populate the Input (JSON) field

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.

Turn into npm-module

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?

embedded resources not rendered if no curies are specified

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
            }
        ]
    }
}

links with absolute URLs cause exceptions

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"
    },
   .....
}

HTTP 406 with request header "Accept: application/hal+json"

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

  • respond to requests with "Accept: application/hal+json"
  • use "Content-type: application/hal+json" in its responses
  • maybe, in addition also respond to requests with "Accept: application/json", as it is doing now

Might be related to #22.

Why is .gitignore excluding html files

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!

Add ability to change users

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.

Links in Properties view are not clickable

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>

Add extension points to render custom POST form

@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

How to include it in a react app

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 ?

Getting HEAD url 405 () error when clicking on NON-GET

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.

Support links as list

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.

wierd errors with current version

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.

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.