I think this question is more about best practices regarding web services and not necessarily limited to ServiceStack only. From what I've read here and on the SS wiki, the 'recommended' way to implement parent-child entities is to break them down via routes.
For example:
/Users/{UserID}
/Users/{UserID}/Entities
Where User is the logged on user, and entities are his/her items. I'm implementing jqueryui autocomplete and here is where I'm suspecting I'm not doing the right thing.
In the script the path needs the Userid, so I have to manually render it in the browser so that it reads:
type: "GET",
url: "svc/users/**8**/entities",
data: { "SearchTerm": request.term, "Format": 'json' },
This smells wrong to me. I have the UserID from the session and I can get it that way. So I wonder if there a better way to access these objects without having to render data directly into markup?
Am I doing this wrong?
On a side note: I know I could place this data in a hidden field and access it via script etc, I am just curious if there is a better/recommended way to do this via sessions while keeping the routes as is.
Generally this is done with another endpoint, Facebook for instance, uses /my/, but you could do what ever you want.
The reason being, it's very likely you will be returning different information for a user about themselves than you share about that user with someone else.
Let's pretend /user/{UserId}/books returns a user's favorite books. If I want to know what someone's favorite books are, I might be interested in the title, and a brief description, but if I want to see (and possibly manage) my list of favorite books then I might want more information, like the day I added the favorite book, or friends of mine that also like the book.
so /user/{UserId}/books returns:
{
"books":[
{ "title":"Hary Potter", "desc":"A boy who is magic..." }
]
}
however /my/books returns:
{
"books":[
{
"title":"Harry Potter",
"desc":"A boy who is magic...",
"friensWhoLikeBook":[
{ "id":1234, "name":"Bob" }
],
"personalCommentsAboutBookNotToBeShared":"This book changed my life..."
}
]
}
Related
I have nextjs app with sentry. I want to add new api route, for example api/status, but I want to exclude it from being sent to sentry as it will clutter logs really fast and use my qouta.
I did a small research and it seems that there is an array of urls you can exclude from being tracked. It's called denyUrls. Read more. I have tried to add my url to this array, but it still tracks this url as part of events:
Sentry.init({
...
denyUrls: [
/api\/status/i,
],
...
});
Am I configuring something wrong or this array is not for the purpose of filtering everts.
If so, what's the best way to filter those? Other option I found which I will try next is beforeSend but it feels a bit overkill to simply exclude url. denyUrls feels like much better fit for what I am trying to achieve
I had the same issue and contacted the support for it. I am directly quoting the support here.
The BeforeSend and DenyUrl are options to filter error events, not transactions. For transaction events, please use the tracesSampler function as described on the page: https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/sampling/#setting-a-sampling-function.
Here is an example to drop all transactions that match a certain name:
tracesSampler: samplingContext => {
if(samplingContext.transactionContext.name == "GET /api/health"){
return 0.0 // never send transactions with name GET /api/health
}
return 0.2 // sampling for all other transactions
}
Note that you might need to customise the function above to better match your scenario.
I hope it will help you ;)
Have a nice day.
I learned about firebase and cloud functions recently and have been able to develop simple applications with them.
I now want to expand my knowledge and really struggling with Trigger Email Extension.
On a specific event on my firebase, I want to fire an email to the user in a custom format, but I am unable to even activate the extension for now.
Can someone please explain with example please about these fields marked in the picture?
I had this question too, but got it resolved. Here's your answer:
"Email documents collection" is the collection that will be read to trigger the emails. I recommend leaving named "mail" unless you already have a collection named mail.
"Users collection (Optional)" refers to a collection (if any) that you want to use in tandem with a user auth system. I haven't had this specific use case yet, but I imagine once you understand how Trigger Email operates, it should be somewhat self-explanatory.
"Templates collection (Optional)" is helpful for templates in which you can use handlebar.js is automatically input specific information per user. (eg. <p>Hello, {{first_name}}</p> etc.) Similar to the previously mentioned collections, you can name it whatever you want.
How to create a template (I have yet to actually implement this, so take this with a grain of salt):
In your templates collection, you want to name each document with a memorable ID. Firebase gives the example:
{
subject: "#{{username}} is now following you!",
html: "Just writing to let you know that <code>#{{username}}</code> ({{name}}) is now following you.",
attachments: [
{
filename: "{{username}}.jpg",
path: "{{imagePath}}"
}
]
}
...specifying a good ID would be following. As you can see, the documents should be structured just like any other email you would send out.
Here is an example of using the above template in javascript:
firestore()
.collection("mail")
.add({
toUids: ["abc123"], // This relates to the Users Collection
template: {
name: "following", // Specify the template
// Specify the information for the Handlebars
// which can also be pulled from your users (toUids)
// if you have the data stored in a user collection.
// Of course that gets more into the world of a user auth system.
data: {
username: "ada",
name: "Ada Lovelace",
imagePath: "https://path-to-file/image-name.jpg"
},
},
})
I hope this helps. Let me know if you have an issues getting this set up.
Referencing this API tutorial/explanation:
https://thinkster.io/tutorials/design-a-robust-json-api/getting-and-setting-user-data
The tutorial explains that to 'follow a user', you would use:
POST /api/profiles/:username/follow.
In order to 'unfollow a user', you would use:
DELETE /api/profiles/:username/follow.
The user Profile initially possesses the field "following": false.
I don't understand why the "following" field is being created/deleted (POST/DELETE) instead of updated from true to false. I feel as though I'm not grasping what's actually going on - are we not simply toggling the value of "following" between true and false?
Thanks!
I think that the database layer have to be implemented in a slightly more complex way than just having a boolean column for "following".
Given that you have three users, what would it mean that one of the users has "following": true? Is that user following something? That alone cannot mean that the user is following all other users, right?
The database layer probably consists of (at least) two different concepts: users and followings; users contain information about the user, and followings specify what users follow one another.
Say that we have two users:
[
{"username": "jake"},
{"username": "jane"}
]
And we want to say that Jane is following Jake, but not the other way around.
Then we need something to represent that concept. Let's call that a following:
{"follower": "jane", "followee": "jake"}
When the API talks about creating or deleting followings, this is probably what they imagine is getting created. That is why they use POST/DELETE instead of just PUT. They don't modify the user object, they create other objects that represent followings.
The reason they have a "following": true/false part in their JSON API response is because when you ask for information about a specific user, as one of the other users, you want to know if you as a user follows that specific user.
So, given the example above, when jane would ask for information about jake, at GET /api/profiles/jake, she would receive something like this:
{
"profile": {
"username": "jake",
"bio": "...",
"image": "...",
"following": true
}
}
However, when jake would ask for the profile information about jane, he would instead get this response:
{
"profile": {
"username": "jane",
"bio": "...",
"image": "...",
"following": false
}
}
So, the info they list as the API response is not what is actually stored in the database about this specific user, it also contains some information that is calculated based on who asked the question.
Using a microPUT would certainly be a reasonable alternative. I don't think anybody is going to be able to tell you why a random API tutorial made certain design decisions. It may be that they just needed a contrived example to use POST/DELETE.
Unless the author sees this question, I expect it's unanswerable. It's conceivable that they want to store meta information, such as the timestamp of the follow state change, but that would be unaffected by POST/DELETE vs. PUT.
I'd like to use the utilities:avatar package, but I'm having some major reservations.
The docs tell me that I should publish my user data, like this:
Meteor.publish("otherUserData", function() {
var data = Meteor.users.find({
}, {
fields : {
"services.twitter.profile_image_url_https" : true,
"services.facebook.id" : true,
"services.google.picture" : true,
"services.github.username" : true,
"services.instagram.profile_picture" : true
}
});
return data;
});
If I understand Meteor's publish/subscribe mechanism correctly, this would push these fields for the entire user database to every client! Clearly, this is not a sustainable solution. Equally clearly, however, either I am doing something wrong, or I am understanding something wrong.
Also: This unscalable solution works fine in a browser, but no avatar icons are visible when the app is deployed to a mobile device, for some reason.
Any ideas?
Separate the issue of which fields to publish from which users you want to publish data on.
Presumably you want to show avatars for other users that the current user is interacting with. You need to decide what query to use in
Meteor.users.find(query,{fields: {...}});
so that you narrow down the list from all users to just pertinent ones.
In my app I end up using reywood:publish-composite to publish the users that are related to the current user via an intermediate collection.
The unscalability of utilities:avatar seems, as far as I can tell, to be a real issue, and there isn't much to be done about it except to remove utilities:avatar and rewrite the avatar URL-fetching code by hand.
As for the avatars not appearing on mobile devices, the answer was simply that we needed to grant permission to access remote URLs in mobile-config.js, like this:
App.accessRule("http://*");
App.accessRule("https://*");
Whenever I encounter code snippets on the web, I see something like
Meteor.subscribe('posts', 'bob-smith');
The client can then display all posts of "bob-smith".
The subscription returns several documents.
What I need, in contrast, is a single-document subscription in order to show an article's body field. I would like to filter by (article) id:
Meteor.subscribe('articles', articleId);
But I got suspicious when I searched the web for similar examples: I cannot find even one single-document subscription example.
What is the reason for that? Why does nobody use single-document subscriptions?
Oh but people do!
This is not against any best practice that I know of.
For example, here is a code sample from the github repository of Telescope where you can see a publication for retrieving a single user based on his or her id.
Here is another one for retrieving a single post, and here is the subscription for it.
It is actually sane to subscribe only to the data that you need at a given moment in your app. If you are writing a single post page, you should make a single post publication/subscription for it, such as:
Meteor.publish('singleArticle', function (articleId) {
return Articles.find({_id: articleId});
});
// Then, from an iron-router route for example:
Meteor.subscribe('singleArticle', this.params.articleId);
A common pattern that uses a single document subscription is a parameterized route, ex: /posts/:_id - you'll see these in many iron:router answers here.