json-server can we use other key instead of id for post and put request - npm

I have fake api for testing in frontend side.
i have seen that id is required to put or post your data in json-server package, my question is can i use different key instead of id for ex.
{
id: 1, ---> i want to change this with my custom id
name: 'Test'
}

Let's see CLI options of json-server package:
$ json-server -h
...
--id, -i Set database id property (e.g. _id) [default: "id"]
...
Let's try to start json-server with new id called 'customId' (for example):
json-server --id customId testDb.json
Structure of testDb.json file: $ cat testDb.json
{
"messages": [
{
"customId": 1,
"description": "somedescription",
"body": "sometext"
}
]
}
Make a simple POST request via $.ajax function (or via Fiddler/Postman/etc.). Content-type of request should be set to application/json - explanation may be found on this project's github page:
A POST, PUT or PATCH request should include a Content-Type: application/json header to use the JSON in the request body. Otherwise it will result in a 200 OK but without changes being made to the data.
So... Make a request from Browser:
$.ajax({
type: "POST",
url: 'http://127.0.0.1:3000/messages/',
data: {body: 'body', description: 'description'},
success: resp => console.log(resp),
dataType: 'json'
});
Go to testDb and see the results. New chunk added. id automatically added with the desired name specified in --id key of console cmd.
{
"body": "body",
"description": "description",
"customId": 12
}
Voila!

I've came up with using custom routes in cases where I need custom id:
json-server --watch db.json --routes routes.json
routes.json:
{ "/customIDroute/:cusomID" : "/customIDroute?cusomID=:cusomID" }

If you start your server using a server.js file (read more about it in the docs), you can define custom ID routes in server.js like this
// server.js
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
server.use(middlewares)
// custom routes
server.use(jsonServer.rewriter({
"/route/:id": "/route?customId=:id"
}))
server.use(router)
server.listen(3000, () => {
console.log('JSON Server is running')
})
And you would start your server with command:
node server.js

Internaly getById from lodash-id is used.
If you use file-based server version the equivalent to cli --id, -i
is router.db._.id = "customId";
If you want to do per resource, you can do it with a middleware like this (put before others):
server.use((req, res, next) => {
if (req.url.includes("/resourceName/")) {
router.db._.id = "code";
} else {
router.db._.id = "pk";
}
next();
});

Related

How do i call third party API data via fastify?

I had a small node server and I use the framework fastify.
In one of my routes, I want to get the data from a third party API.
I tried the following snippet:
fastify.route({
method: 'GET',
url: 'https://demo.api.com/api/v2/project/',
handler: async function ({ params, body}, reply) {
if (!body) return reply.send({ sucess: false })
console.log('testing')
console.log(body)
return reply.send({ sucess: true })
}
})
Unfortunately, I cannot call the URL by get because GET url's can only start with '/'.
How do i call a third pary api via fastify? do i need a extention?
If you need to define a route (like http://localhost:3000/) that proxies another server you need to use fastify-http-proxy.
Or if you need to call another endpoint and manage the response, there is the fastify.inject() utility but it is designed for testing.
Anyway, I think the best approach is to use some HTTP client like got
const got = require('got') // npm install got
fastify.get('/my-endpoint', async function (request, reply) {
const response = await got('sindresorhus.com')
console.log(response.body)
// DO SOMETHING WITH BODY
return { sucess: true }
})
Proxy your http requests to another server, with fastify hooks.
here is the example in fastify-http-proxy
server.register(require('fastify-http-proxy'), {
upstream: 'http://my-api.example.com',
prefix: '/api', // optional
http2: false // optional
})
https://github.com/fastify/fastify-http-proxy/blob/master/example.js

Meteor - Rest API in existing project using iron:router - html sent?

I have an existing project that serves a webapp. I want to add a REST webservice to get data in and out.
some code:
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
notFoundTemplate: 'notFound'
});
Router.map(function() {
this.route('GeolocationBGRoute', {
path: '/api/v1/geolocation/',
where: 'server',
layout: null,
action: function () {
// GET, POST, PUT, DELETE
var requestMethod = this.request.method;
// Data from a POST request
var requestData = this.request.body;
// log stuff
console.log('GeolocationBG post: ' + requestMethod);
console.log(JSON.stringify(requestData));
// TODO: security/validation
// require some security with data
// validate userId/uuid/etc (inside Meteor.call?)
// Can insert into a Collection from the server (or whatever)
if (GeolocationLog.insert(requestData)) {
this.response.writeHead(200, {'Content-Type': 'application/json'});
this.response.end('ok');
return;
}
// if we end up with an error case, you can return 500
this.response.writeHead(500, {'Content-Type': 'application/json'});
this.response.end('failure');
}
});
});
When I call this page with
curl -v -H "Content-Type: application/json" -X PUT --data '{"foo":"bar"}' 'http://localhost:3000/api/v1/geolocation'
I get all the HTML back from the layoutTemplate: 'layout' - how can I just make a raw restful API which just returns JSON without the HTML of the existing project?
Add the Router.configure only on the client - either in a file under the client directory, or guard that section with an if (Meteor.isClient).
I like to keep my routes in a shared directory, but I define all of the controllers and front-end configuration stuff on the client.

header Content-Type case sensitivity issue in testing with superagent and jasmine-ajax

I'm using superagent and jasmine-ajax in my testing environment (karma with jasmine adapter).
I noticed an issue pertaining to case-sensitivity on the response headers when trying to mock responses that superagent will then handle.
Testing code:
it('should parse the response as json', function() {
var response = '{ "foo" : "bar" }';
superagent.get('/some/url', function(
expect(response.body).toEqual({ foo: "bar" });
});
jasmine.Ajax.requests.mostRecent().response({
status: 200,
// uncomment following line to make this test pass
// responseHeaders: { "content-type" : "application/json" },
responseText: response
});
});
In superagent.js line ~695 has:
this.header['content-type'] = this.xhr.getResponseHeader('content-type');
In mock-ajax.js line ~175 has
this.responseHeaders = response.responseHeaders ||
{"Content-type": response.contentType || "application/json" };
So, obviously within each respective library, there is a discrepancy with casing, but, according to spec, all the research I've done says that this field is case-insensitive. I thought that it might be an issue with PhantomJS, but I just tried using Chrome as well, but the same issue is present.
Any insight would be appreciated.

mootools Request class and CORS

I'm trying to use CORS to have a script do an Ajax request to geonames.
My script calls this web service method: http://www.geonames.org/export/web-services.html#findNearby
If you check the response headers of the sample call, they include:
Access-Control-Allow-Origin: *
When I try this with mootools (version 1.4.5 just downloaded):
var urlGeonames = "http://api.geonames.org/findNearbyPlaceName";
var req = new Request({
method: 'get',
url: urlGeonames,
data: {
'lat': '89.18',
'lng': '-0.37',
'username': 'myusername',
'radius': '5'
}
}).send();
then I get an error that says :
XMLHttpRequest cannot load
http://api.geonames.org/findNearbyPlaceName?lat=89.18&lng=-0.37&username=myusername&radius=5.
Origin http://127.0.0.1 is not allowed by Access-Control-Allow-Origin.</pre>
On the other hand, when I try old style Ajax code like this:
invocation = new XMLHttpRequest();
if(invocation)
{
invocation.open('GET', urlFlickr, true);
invocation.onreadystatechange = handler;
invocation.send();
}
then it works and I get the XML response in the XHR responseXML.
I found this post A CORS POST request works from plain javascript, but why not with jQuery? that is similar. But here I'm not dealing with my server so I can only work on the javascript side.
Has anyone worked with CORS and mootools and can help on this issue ?
Thanks so much
JM
Hey man check out mootools more JSONP this will solve your problem:
http://mootools.net/docs/more/Request/Request.JSONP
Also it looks like your forgetting to ask for it in JSON format from geonames.org
Try something like:
var myJSONP = new Request.JSONP({
url: 'http://api.geonames.org/findNearbyPlaceNameJSON',
data: {
'lat': '89.18',
'lng': '-0.37',
'username': 'myusername'
},
onRequest: function(url){
// a script tag is created with a src attribute equal to url
},
onComplete: function(data){
// the request was completed.
console.log(data);
}
}).send();
Hope this helps!
The first answer on this other thread:
MooTools CORS request vs native Javascript
Might help.
Basically, the X-Requested-With header is automatically sent by the Mootools with the request, but the server either has to be configured to accept that header or you can remove it using
delete foo.headers['X-Requested-With'];
Before calling
foo.send();
To allow it by the server, you can add this to the .htaccess file of your script that gives back the JSON data:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
So yours would look like:
var myJSON = new Request({
url: 'http://api.geonames.org/findNearbyPlaceNameJSON',
data: {
'lat': '89.18',
'lng': '-0.37',
'username': 'myusername'
},
onRequest: function(url){
// a script tag is created with a src attribute equal to url
},
onComplete: function(data){
// the request was completed.
console.log(data);
}
});
delete myJSON.headers['X-Requested-With'];
myJSON.send();

nodejs restler module post test call EMPTY body?

I am writing some tests for my nodejs app. Tests work ok, the only problem I'm having (using restler) is that when I test a post request the body sent in the request is always empty.
This is what I'm doing:
rest.post('http://localhost:3000/api/testpost1', {
name : "my name"
}).on('complete', function(data,res) {
console.log("status code",res.statusCode)
});
The body in the req.body on the server is always equal to: {}
What am I doing wrong?
Do this:
rest.post('http://localhost:3000/api/testpost1', {
data: {name : "my name"}
}).on('complete', function(data,res) {
console.log("status code",res.statusCode)
});