How do I select most popular objects, e.g list most read articles - api

I am looking at creating a social reader app on which users can read articles I publish.
On the app home page, I want to list the most read articles.
Is there a way to do this client side using the FB API, or can I get the data from the FB API server side some how and store it?
or do I need to collate the read count in my own data store and create the list server side?
I am planning to have custom objects and actions and I essentially want a list of most popular objects by action

Is there a way to do this client side using the FB API
No, I don't think so.
or can I get the data from the FB API server side some how and store it?
Of course, just save it to a database and do your logic. For example, increment the count for each page in your database table when a user reads the article. Then use an SQL query that pulls the "TOP X"
select top 10 * from articletable order by NumRead asc
When a user makes a call to news.read an action instance id is returned inspect that for the respective article right after making the call
FB.api(
'/me/news.reads',
'post',
{ article: 'URL_TO_ARTICLE' },
function(response) {
if (!response || response.error) {
alert('Error occured');
console.log(response.error);
} else {
FB.api(
response.id, function(response) {
var data = response['data'];
var video = data['article'];
// Send to your database logic article['id'];
});
}
});
Or you skip the second API call altogether and just save the current page in your table and increment its count.

Related

How to attach multiple parameters to an API request?

I built my own simple REST API with Express and now I'm consuming it from my client (Vue.js)
So in my page I access all the data from this endpoint: GET /api/books, and it works fine
Now I also have a "sort by" button where I want to get the data by the latest entries. I don't know if that's a good way or if I have to handle this in the backend but what I do is calling the same endpoint which is GET /api/books and sorting the data to get them the right way
For ex:
sortByLatest() {
axios
.get("/api/books")
.then(res => {
const books = res.data;
const sortedBooks = books.sort((a, b) => b.createdAt > a.createdAt ? 1 : -1
);
this.books = sortedBooks;
})
// catch block
}
I do that for everything. If I need a limited number of results or a specific property from the data I have to write some logic in the axios .then block to sort or filter what I want. Is this bad practice?
But that's not my actual problem
My problem is, in addition of sorting by the latest entries, I also want to filter the results by a specific property. The problem is when I click the A button it's gonna filter the books by a specific property, and when I click the B button it's gonna sort them buy the latest entries, but not both at the same time!
And what if I want additionnal things like limit the number of results to 10, filter by other properties etc... I want to be able to create requests that ask all those things at once. How can I do that? Do I have to build that in the backend?
I saw some websites using url parameters to filter stuff, like /genre=horror&sort=latest, is that the key of doing it?
Thank you for your time

Fetching data from multiple APIs using Graphql / REST

I have design question, on the approach that should fetch information about an entity from multiple applications and publish the result to the frontend at real-time. All of these applications can produce results abiding to a particular schema.
Currently I am using GraphQL, to combine the results from both the application source and concatinating the result to the frontend for users to compare and validate the data.
Ex: The query below, fetches the information of a client from two different applications through RESTful data source
const resolvers = {
Query: {
client: async (_source, { clientId }, { dataSources }) => {
clientApp1 = await dataSources.App1ClientsAPI.getClient(clientId);
clientApp2 = await dataSources.App2ClientsAPI.getClient(clientId);
const client = [].concat(clientApp1, clientApp2);
return client;
},
},
};
Schema
type Client {
ssnNumber: String
firstName: String
lastName: String
dateofBirth: String
clientId: Float
source: String
contactList: [Contact]
addressList: [Address]
}
Currently this approach is working fine for top level entity like Client, but when we go to bottom of the chain, like contacts, address, transactions, the number of resultset returned expands drastically. With this approach I see 2 drawbacks, pretty sure, there could be more, but these are the once which are critical for me
Unable to add a filter in the backend Ex: return only App1 data
Unable to control number of records returned by each application at the lower level entities [pagination]
Question
1.Should I modify the approach to use Schema Stiching or GraphQL federation for better performance
2.Any better options outside of Graphql that I should look for, for combining the results from Multiple API's

Use filtered list in datatables to send multiple emails

I'd like to be able to send emails based on a search completed in Datatables. I use a json array created from a mysql db and serverside datatables.js processing to create the table. The table creates a filtered list (Showing 1 to 35 of 35 entries (filtered from 60 total entries)), and I'd like to be able to send an email to those 35 people. I'm very new to ajax and javascript, but have some experience in php. Is this possible?
It's absolutely possible.
You may need to extract your visible rows data:
var selectedRows = datatable.rows({filter:'applied'}).data()
Pass that data via $.ajax() call to your backend php-script and perform necessary 'e-mail' job server side.
Without your code and knowing exact environment, I believe, that's the best I could say.
I tried:
$('#export').click(function () {
$.ajax({
url : 'emget.php',
type : 'post',
data : table.column(4,{search:'applied'}).data().toArray(),
dataType: 'json',
success : function(returnedData) {
console.log(returnedData);
}
});
});
When I view the output, it seems to put out the correct number of records, but it says "Undefined" for each record it seems to try to export. Column 4 has the email addresses that I would need to pass to PHP.

Laravel query parameters or pretty parameters for api

i am willing to know which is the best practice to use parameters for developing an api
//url
http://localhost:8000/api/my_orders/1/10/1
//route
Route::get('/my_orders/{user_id}/{limit}/{page}', 'ApiControllers\OrderController#getOrdersByUser');
//method
public function getOrdersByUser($user_id, $limit, $page)
{
//logic using $user_id, $limit, $page
}
or
//url
http://localhost:8000/api/my_orders?user_id=1&&limit=5&&page=1
//route
Route::get('/my_orders', 'ApiControllers\OrderController#getOrdersByUser');
//method
public function getOrdersByUser(Request $request)
{
//logic using $request->user_id, $request->limit, $request->page
}
this api is for mobile applications and for front end Vue application
thank you
Laravel has pagination built in, it will check for page and perpage query string arguments using paginate() or something that uses Paginator related methods for fetching a subset of your data.
So when you have ?page=1&perpage=20 and you use paginators, they will pick these up automatically.
For REST API endpoints, try and make the urls as descriptive as possible and based on your models.
// get a list of orders
GET /api/orders
// get a list of orders belonging to user 1
GET /api/orders?user_id=1
// get a paginated list of 20 orders belonging to user 1
GET /api/orders?user_id=1&page=1&perpage=20
You are calling your endpoint my_orders, which basically says it will return orders owned by the authenticated user. So, in my opinion, it wouldn't make sense here to include a user_id argument.
// get a list of orders owned by the authenticated user
GET /api/my_orders
You can use my_orders, but more descriptive will be to use a url like:
// get a list of orders owned by user
GET /api/users/{user_id}/orders
Edit:
In your case, you probably want to create a UserOrderController
public function index($user_id)
{
// first fetch user, if fetch fails show error
$user = User::findOrFail($user_id);
// maybe add some code here to check if the authenticated user is allowed to view this user's orders
// return paginated orders
return $user->orders()->paginate();
}
And you would need to define the relations in the models:
App/User.php
public function orders()
{
// assuming orders table has a column user_id
return $this->hasMany(Order::class);
}
App/Order.php
// inverse relation
public function user()
{
return $this->belongsTo(User::class);
}
I use 1st way for only those parameters which are associated with DB, like user_id here, because it reduces 1 step for me to get the specific data from DB of that particular ID. for more dynamic url laravel will go to this route even when you supply the wrong values and you have to apply the regix to avoid that.
Secondly, URLs like 2/20/4 wouldnt make any sense and hard to understand. So the best way in my opinion is the second way.

Right way to dynamically update view in Angular

What is the right way to updated the Model in the view, say after a successful API POST. I've a textarea, something like in a Twitter, where a user can enter text and post. The entered text must show up soon after it is posted successfully.
How to achieve this? Should I make another call to get the posts separately or is there any other way to do this?
My Code looks like
feedsResolve.getFeeds().then(function(feeds){
$scope.feeds = feeds;
}
where feedsResolve is a service returning a promise
$scope.postFeed = function(){
var postObj = Restangular.all('posts');
postObj.post( $scope.feed.text ).then(function(res){
//res contains only the new feed id
})
}
How do I update the $scope.feeds in the view?
I assume you are posting a new post and that generally posts look like:
{
id: 42,
text: 'This is my text'
}
In this case you can do something like:
$scope.postFeed = function(){
var postObj = Restangular.all('posts');
var feedText = $scope.feed.text;
postObj.post( feedText ).then(function(res){
$scope.feeds.push({ id: res.id, text: feedText});
})
};
A better practice when writing restful service though is to just have your POST return an actual JSON object with the new feed that was added (not just the id). If that were the case you could just add it to your feeds array.
If your JSON object is complex, this practice is the most common an easiest way to handle this without needing extra requests to the server. Since you already are on the server, and you've likely already created the object (in order to be able to insert it into the database), all you have to do is serialize it back out to the HTTP response. This adds little to no overhead and gives the client all the information it needs to effortlessly update.