In a schema with optional values such as code in the example:
'code': {
'type': 'string',
},
'name': {
'type': 'string',
'required': True,
},
'email': {
'type': 'string',
'required': True
}
Let's say there's an inserted document with a value for code. Can I unset the code key like mongodb $unset does, using Eve somehow?
One way to achieve this is to setup a default projection for the endpoint.
Limiting the Fieldset Exposed by the API Endpoint
By default API responses to GET requests will include all fields defined by the corresponding resource schema. The projection setting of the datasource resource keyword allows you to redefine the fields.
people = {
'datasource': {
'projection': {'username': 1}
}
}
The above setting will expose only the username field to GET requests, no matter the schema defined for the resource.
Another option is to leverage MongoDB Aggregation Framework itself. Just set the endpoint so that a aggregation is performed before data is returned to the client. The following should work (see the docs for details):
posts = {
'datasource': {
'aggregation': {
'pipeline': [{"$unset": "code"}]
}
}
}
You need Eve v0.7 for aggregation support.
I doubt you can do it with a PATCH request, but a PUT request should do.
import requests
# get original doc
resp = requests.get(document_url)
# prepare a new document
doc = resp.json()
new_doc = {k: v for k, v in doc.items() if not k.startswith('_')}
del new_doc['code']
# overwrite the complete document
resp = requests.put(document_url, json=new_doc, headers={'If-Match': doc['_etag']}
Related
I don't see any good documentation about how to execute GraphQL APIs using F# with Http.fs
Kindly share if you have the correct syntax available or point to the correct documentation for the same. I was trying with the Star Wars API given here: https://www.rithmschool.com/blog/an-introduction-to-graphql-queries
URL: https://swapi.graph.cool
Header: 'Content-Type': 'application/json'
JSON Body:
query {
Film (title:"A New Hope" ) {
director
characters {
name
}
}
}
Expected Response same as: https://swapi.graph.cool/
I'm not familiar with Http.fs, but here is a small working example of calling the API using the F# Data Http utility:
Http.RequestString
( "https://swapi.graph.cool",
httpMethod="POST", headers=[ HttpRequestHeaders.ContentType("application/json") ],
body=TextRequest("{\"query\": \"{ allFilms { title } }\"}") )
The main thing is that the body needs to be a JSON value where the actual query is a string stored in a record with a field named "query", i.e. {"query": "...."}.
I want to track my custom processes through Zabbix (v2.4.8). I am generating the following json object and sending it through UserParameter=service.value[*],/usr/lib/zabbix/externalscripts/custom1.bash:
{
"data":[
{
"{#NAME}":"ntp",
"{#VALUE}":"1"
},
{
"{#NAME}":"mysql",
"{#VALUE}":"1"
},
{
"{#NAME}":"prometheus",
"{#VALUE}":"0"
},
{
"{#NAME}":"apache2",
"{#VALUE}":"0"
}
]
}
Also, creating an item prototype and graph prototype inside a new template with a new discovery rule, having the following information:
Discovery rule name: Service Graph
Type: Zabbix Agent
key: service.value
Item Prototype name: Service {#NAME} Graph
Type: Zabbix Agent
key: service.value[{#NAME},{#VALUE}]
Type of info: Numeric(Unsigned) & Decimal
When I apply these settings, the items keep giving the following error:
Not supported: Received value [{ "data":[ { "{#NAME}":"ntp", "{#VALUE}":"1" }, { "{#NAME}":"mysql", "{#VALUE}":"1" }, { "{#NAME}":"prometheus", "{#VALUE}":"0" }, { "{#NAME}":"apache2", "{#VALUE}":"0" } ]}] is not suitable for value type [Numeric (unsigned)] and data type [Decimal]
I have to create a graph prototype with these settings, so I cannot mention type as "Text" for obvious reasons.
Another question: The graphs thus generated are not clickable at all like the other existing graphs.
Please let me know where I am going wrong.
If your service.value key generates JSON, that should be used with the LLD rule only. You should not send any values in it. The key to be used in the prototypes should be like any normal key they only returns values it was asked for, do not use the LLD-generating key there.
Your current JSON looks like you might be able to use the built-in items for process monitoring, but that is hard to be sure about without additional detail.
Also note that [*] in the UserParameter definition is not needed if you do not pass parameters to this key.
I defined a GraphQL Mutation using graphql-relay but am having issues figuring out how to submit a mutation to it.
Here is the relevant schema:
const userType = new GraphQLObjectType({
name: 'User',
description: 'user',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'The UUID for the user.',
resolve(user) {
return user.uuid;
},
},
})
});
const registerUser = mutationWithClientMutationId({
name: 'registerUser',
inputFields: {
},
outputFields: {
user: {
type: userType,
resolve: (payload) => {
models.user.findById(payload.userId);
}
},
},
mutateAndGetPayload: (args) => {
var newUser = models.user.build().save();
return {
userId: newUser.id,
};
}
});
const rootMutation = new GraphQLObjectType({
name: 'RootMutationType',
fields: {
registerUser: registerUser,
},
});
const schema = new GraphQLSchema({
query: rootQuery,
mutation: rootMutation,
});
What should an HTTP call look like to register a new user and get back the userId?
Thanks!
I want to point out that I see that you're saying that your mutation requires no parameters - how does it know what the new user's details are? You'll probably need some parameters on that mutation, eventually. They would be available to your mutateAndGetPayload on that first function parameter. (I'm not saying every mutation needs parameters, but this one probably does)
If you're using Relay, there is some pretty good information on the official document as to how to use your mutations from Relay. Particularly down at the bottom where it shows the various mutator configs. If you're using connections, you may want to use RANGE_ADD to add this new account to the Relay store manually, otherwise if you'd like to perform a more broad refetch you can use FIELDS_CHANGE. You said you need the new user id after the mutation finishes. If you're using Relay, you may need to look into REQUIRED_CHILDREN to specify that regardless of the computed query that Relay will build, you always want that id to be queried.
The output of your mutation is a userType, so you'd be able to access it with a fragment on the payload type, which would probably be RegisterUserPayload, that might look something like ...
fragment on RegisterUserPayload {
user {
id
}
}
Now, that's assuming you're using Relay. If you'd like to try this out manually via GraphiQL, then you can use the examples of how to do mutations through there on the GraphQL Mutation docs. There's a direct example of how you'd query your mutation.
Last, since you asked how to do this at a low level of issuing the HTTP request yourself, for that you can look at express-graphql documentation, which explains how to query it.
I figured out a mutation format that worked:
mutation RootMutationType {
registerUser(input:{clientMutationId:"123"}){
clientMutationId, user { id }
}
}
I want to use coturn with oAuth. If I understood it correctly I need to do two things:
Storing the oAuth tokens in the database coturn is using
Sending the ACCESS-TOKEN and USERNAME STUN attributes
First point is clear but how do I need to change my WebRTC client to achieve the second point?
Without oAuth I would initialize my RTCPeerConnection like this:
var configuration = {
'iceServers': [{
'url': 'turn:turn.example.org',
'username': 'user',
'credential': 'password'
}]
};
var pc = new RTCPeerConnection(configuration)
The WebRTC 1.0 draft defines a RTCIceCredentialType enum so i would think I need to change my configuration like this:
var configuration = {
'iceServers': [{
'url': 'turn:turn.example.org',
'username': 'kid',
'credential': 'oAuthToken',
'credentialType': 'token'
}]
};
Using Wireshark I can't see the ACESS-TOKEN attribute. Any ideas or does anyone know a working example?
It seems like things changed a bit since original question was asked. The webrtc-pc#1033 pull-request alters the spec and introduces the following iceServers configuration syntax:
var configuration = {
'iceServers': [{
"urls": "turns:turn.example.net",
"username": "username",
"credential": {
"macKey": "...",
"accessToken": "..."
},
"credentialType": "oauth"
}],
...
}
See RTCIceServer documentation page for more configuration examples.
The order of precedence that ASP.NET MVC uses when it binds models for incoming requests is bothering me in the context of REST. Essentially, MVC binds models using values in the following order of precedence:
POST body
Route (URL)
Query string values
What bothers me is how that trumps a resource's Uri with values from the body of the message.
For example, I could have a RESTful resource exposed as follows:
/dogs/
... returning:
[{
'name': 'Fido',
'color': 'brown',
'_links': {
'self': { 'href': '/dogs/7' }
}
},
{
'name': 'Spot',
'color': 'spotted',
'_links': {
'self': { 'href': '/dogs/5' }
}
}]
Note that with the "self" link (HAL style), I have everything I need to modify the dogs by PUTting those resources back to the server without needing their "id" values.
PUT /dogs/7
{
'name': 'Super Fido',
'color': 'rainbow'
}
The server has everything needed to update the dog, with no confusion. MVC will model-bind everything nicely into my model, including the id (sourced from the route).
However, some API styles I have seen include the 'id' in the message body, so that it looks like this:
GET /dogs/7
{
'id': 7,
'name': 'Super Fido',
'color': 'rainbow'
}
But fundamentally what bothers me the most is that if I have a route defined like "{controller}/{id}", and the client does the following:
PUT /dogs/7
{
'id': 5,
'name': 'Snowy',
'color': 'white'
}
... then MVC will model bind the 'id' to 5 (from the message body), and not 7 (from the route), yet based on the resource URI that my client provided, they should have been updating Fido's information. This would be akin to trying to save a document to your hard drive in a certain location, and because of something in the document, having it be automatically saved somewhere else.
How would one go about changing the out-of-the-box model binding precedence in ASP.NET MVC to prioritize the route values over the message body (when conflicts exist), and would this be a good thing to do in this context?