RejectedSoftware Forums

Sign up

Cannot get rest to work

I am trying to create a simple rest server that responds to scripts that I attach to pages I visit(using Greasemonkey).

I cannot get the vibe.d project to respond to requests.

I have used the example project

import std.typecons : Nullable;
import vibe.d;
import std.stdio;

@path("/")
interface IMyAPI
{
	// GET /api/greeting
	@property string greeting();

	// PUT /api/greeting
	@property void greeting(string text);

	// POST /api/users
	@path("/users")
	void addNewUser(string name);

	// GET /api/users
	@property string[] users();

	// GET /api/:id/name
	string getName(int id);

	// GET /some_custom_json
	Json getSomeCustomJson();
}

// vibe.d takes care of all JSON encoding/decoding
// and actual API implementation can work directly
// with native types

class API : IMyAPI
{
	private {
		string m_greeting;
		string[] m_users;
	}

	@property string greeting() { return m_greeting; }
	@property void greeting(string text) { m_greeting = text; }

	void addNewUser(string name) { m_users ~= name; }

	@property string[] users() { return m_users; }

	string getName(int id) { return m_users[id]; }

	Json getSomeCustomJson()
	{
		Json ret = Json.emptyObject;
		ret["somefield"] = "Hello, World!";
		return ret;
	}
}

// actual usage, this is usually done in app.d module
// constructor

void static_this()
{
	import vibe.http.server, vibe.http.router;


	auto settings = new HTTPServerSettings;
	auto router = new URLRouter;
	router.registerRestInterface(new API());
		
			
	settings.options |= HTTPServerOption.parseJsonBody;
	settings.bindAddresses = ["::1", "127.0.0.1"];
	settings.port = 80;
	listenHTTP(settings, router);

}




I run this then try to make a request either using js or soapUI but they always fail with connection error.

The javascript request is

$.ajax({
  url: 'http://127.0.0.1/',
  type: 'GET',
  //contentType: "application/json; charset=utf-8",
  contentType: "application/json"
  dataType: "json",      
  data: 'greeting', // or $('#myform').serializeArray()
  success: function() { alert('GET completed'); },
  error: function (qXHR, exception) {   alert(JSON.stringify(qXHR)); },
  done: function(msg) { alert("DONE: " + msg ); }   

});

I am new to using rest so I do not know if I am doing something wrong, if it is a configuration issue, or what.

I have tried various things. I ultimately simply want to send the url to the vibe.d rest app.

Any ideas? And any ideas to get some type of feedback so I know if at least the request is making it in to the vibe d framework?

Thanks.

Re: Cannot get rest to work

  //contentType: "application/json; charset=utf-8",
  contentType: "application/json",

(left the comma out as I was trying to see if the charset created the issue or not... doesn't change any of the problems)

Re: Cannot get rest to work

I should also mention that a normal vibe D server works fine so I do believe that vibe.d is getting the request but not acting on them, hence, something wrong with the example I posted or the specific request parameters I posted.

Re: Cannot get rest to work

On Sun, 01 Jan 2017 21:28:30 GMT, Inquie wrote:

I am trying to create a simple rest server that responds to scripts that I attach to pages I visit(using Greasemonkey).

I cannot get the vibe.d project to respond to requests.

I have used the example project

import std.typecons : Nullable;
import vibe.d;
import std.stdio;

@path("/")
interface IMyAPI
{
	// GET /api/greeting
	@property string greeting();

	// PUT /api/greeting
	@property void greeting(string text);

	// POST /api/users
	@path("/users")
	void addNewUser(string name);

	// GET /api/users
	@property string[] users();

	// GET /api/:id/name
	string getName(int id);

	// GET /some_custom_json
	Json getSomeCustomJson();
}

I run this then try to make a request either using js or soapUI but they always fail with connection error.

The javascript request is

$.ajax({
  url: 'http://127.0.0.1/',
  type: 'GET',
  //contentType: "application/json; charset=utf-8",
  contentType: "application/json"
  dataType: "json",      
  data: 'greeting', // or $('#myform').serializeArray()
  success: function() { alert('GET completed'); },
  error: function (qXHR, exception) {   alert(JSON.stringify(qXHR)); },
  done: function(msg) { alert("DONE: " + msg ); }   

});

I am new to using rest so I do not know if I am doing something wrong, if it is a configuration issue, or what.

As far as I can see you don't have a route matching the root. If you want to make a request for the greeting method that needs to be in the URL, i.e. url: 'http://127.0.0.1/greeting'.

/Jacob Carlborg

Re: Cannot get rest to work

On Mon, 02 Jan 2017 08:29:34 GMT, Jacob Carlborg wrote:

On Sun, 01 Jan 2017 21:28:30 GMT, Inquie wrote:

I am trying to create a simple rest server that responds to scripts that I attach to pages I visit(using Greasemonkey).

I cannot get the vibe.d project to respond to requests.

I have used the example project

import std.typecons : Nullable;
import vibe.d;
import std.stdio;

@path("/")
interface IMyAPI
{
	// GET /api/greeting
	@property string greeting();

	// PUT /api/greeting
	@property void greeting(string text);

	// POST /api/users
	@path("/users")
	void addNewUser(string name);

	// GET /api/users
	@property string[] users();

	// GET /api/:id/name
	string getName(int id);

	// GET /some_custom_json
	Json getSomeCustomJson();
}

I run this then try to make a request either using js or soapUI but they always fail with connection error.

The javascript request is

$.ajax({
  url: 'http://127.0.0.1/',
  type: 'GET',
  //contentType: "application/json; charset=utf-8",
  contentType: "application/json"
  dataType: "json",      
  data: 'greeting', // or $('#myform').serializeArray()
  success: function() { alert('GET completed'); },
  error: function (qXHR, exception) {   alert(JSON.stringify(qXHR)); },
  done: function(msg) { alert("DONE: " + msg ); }   

});

I am new to using rest so I do not know if I am doing something wrong, if it is a configuration issue, or what.

As far as I can see you don't have a route matching the root. If you want to make a request for the greeting method that needs to be in the URL, i.e. url: 'http://127.0.0.1/greeting'.

/Jacob Carlborg

Well, I don't seem to understand, I tried that, same issue.

I thought data added the resource to get rather than putting it in the url, tried a similar thing in soap and no worky either.

I've tried adding end point = http://127.0.0.1 and resource = /greeting or end point = http://127.0.0.1/greeing and resource = <null> with same issue. Tried that with JS too(url = the endpoint's above and data = the resources above).

They all return error.

Re: Cannot get rest to work

I tried a different example I found online and it worked fine... not sure why:

https://tour.dlang.org/tour/en/vibed/json-rest-interface

Maybe a bug in the original example?

(All I did was copy and paste, added bindAddress to localhost and changed port)

Re: Cannot get rest to work

On Mon, 02 Jan 2017 09:20:12 GMT, Inquie wrote:

Well, I don't seem to understand, I tried that, same issue.

I thought data added the resource to get rather than putting it in the url, tried a similar thing in soap and no worky either.

No, "greeting" needs to be part of the URL, it's the endpoint. The parameters (declared in the interface) are what go in the data, serialized as JSON. I tried your vibe.d application and it works, you just need to call it correctly. Here's an example using curl:

$ curl -H 'Content-Type: application/json' -X  PUT -d '{"text":"foobar"}' localhost/greeting
$ curl localhost/greeting
"foobar"

Note that the HTTP header Content-Type: application/json needs to be supplied for it to work as well. But I assume jQuery does that automatically, while curl doesn't.

Re: Cannot get rest to work

On Mon, 02 Jan 2017 13:14:16 GMT, Jacob Carlborg wrote:

On Mon, 02 Jan 2017 09:20:12 GMT, Inquie wrote:

Well, I don't seem to understand, I tried that, same issue.

I thought data added the resource to get rather than putting it in the url, tried a similar thing in soap and no worky either.

No, "greeting" needs to be part of the URL, it's the endpoint. The parameters (declared in the interface) are what go in the data, serialized as JSON. I tried your vibe.d application and it works, you just need to call it correctly. Here's an example using curl:

$ curl -H 'Content-Type: application/json' -X  PUT -d '{"text":"foobar"}' localhost/greeting
$ curl localhost/greeting
"foobar"

Note that the HTTP header Content-Type: application/json needs to be supplied for it to work as well. But I assume jQuery does that automatically, while curl doesn't.

I eventually got it to work. There seems to be a lot of broken code in the world ;/

GM_xmlhttpRequest({

method: "POST",
url: "http://127.0.0.1/add-chapter",
data: JSON.stringify({title:"test"}),
headers: {
	"Content-Type": "application/json",
},
onload: function(response) { alert(JSON.stringify(response)); }  

});

But it only works if you allow cross site content... (had to use a plugin that disables it for the site I was working on(youtube)).

(again, I tried both ways with the firs test case and it failed, while in the second it worked fine... so it might have been on my end, but I'm not gonna go try out the first example again... to much wasted time trying to get simple stuff to work in the first place)

Re: Cannot get rest to work

On Mon, 02 Jan 2017 13:47:44 GMT, Inquie wrote:

But it only works if you allow cross site content... (had to use a plugin that disables it for the site I was working on(youtube)).

Try with only the path, i.e. url: "/add-chapter". Note, that it's not possible to make an AJAX request to another site than the site that contains the JavaScript. For that you need a backend server that forwards the request.

/Jacob Carlborg