How to retrieve multiple users at once with the GitHub API? - github

I'm able to get a single user, or all users created since a timestamp, or where there is some search match with the GitHub API.
https://developer.github.com/v3/users/#get-a-single-user
https://developer.github.com/v3/users/#get-all-users
https://developer.github.com/v3/search/#search-users
What I haven't been able to figure out is if there is a way to send something like a list of logins and get back all of those users at once.
My use case is that I'm pulling back a list of members off of an org. This provides me with enough data that I could loop through each individual user and get the detailed user data that I need this way, but I would rather not be hammering GitHub's API with a bunch of extra requests if it is not necessary.

Using GraphQL API v4, you could build a dynamic query with as many user you have in your array & use aliases for each one :
query {
user1: user(login: "aisalmi") {
...UserFragment
}
user2: user(login: "bertrandmartel") {
...UserFragment
}
user3: user(login: "molokoloco") {
...UserFragment
}
}
fragment UserFragment on User {
login
name
}
I also use a fragment to avoid field duplication
Test it in the explorer

Related

REST-API users.list with the eppn

Since we have some integrations with Rocket.Chat, we do use the API to create, query and subscribe User of a System to the Rocket.Chat.
We use the SAML authentication and we work with the eppn parameter.
Before it was easy to search for a user in rocket chat with the eppn, since you could query the eppn with the API users.list.
api/v1/users.list?query={"eppn":"eppn-of-user"}
After I upgraded the Rocket.Chat to the 3.9 Version, I saw that it is not possible to query the eppn with the users.list API.
The structure of User is changed and now the eppn parameter is a child of services.saml.
I can query the eppn in the MongoDB like this:
coll.find({'services.saml.eppn': "user-eepn"})
But no way to query the eppn with the API:
api/v1/users.list?query={'services.saml.eppn': "user-eppn"}
{
"success": false,
"error": "Invalid query parameter provided: \"{'services.saml.eppn': \"user-eppn\"}\" [error-invalid-query]",
"errorType": "error-invalid-query",
"details": {
"helperMethod": "parseJsonQuery"
}
}
Does anyone have an idea about it?
Thank you!
So everyone, I just got the solution to my problem, if any one will have the same problem.
First of all for the EJSON parse function the query must be written like this:
api/v1/users.list?query={"services.saml.eppn": "user-eppn"}
But the second problem is that Rocket.Chat doesn't allow a query on the services parameter.
It is a problem of permissions, so to query the services parameter and then the eppn parameter, there must be permission given to the User.

How to design model for storing day wise timings?

I am designing a schema for doctor's appointments. The doctor will be given the option to update his/her timings for individual days of the month. Also there is no limit to months. For instance, the doctors will be able to update the timings for any days of future or current month. (Only previous dates will be disabled). The front end part has been done but what I fail to understand is how to create the mongo model for it. Of course I can not have dates for all months stored in the model. What is the method to address this problem? TIA
If it was me that had such project, I would start with 5 collections:
one for users (so you know who did what)
one for patients (recording all about the patient, including mobile number)
one for doctors (so you can show a list while registering time)
one for time registrations (with all details of the registration)
one for logging everything a user does
so you can go back in time and to know how did what... it's never to point the finger to the person that made the mistake but look at it as a very easy way to find out what it happened and how can you prevent it from happening again.
the content of each document is entirely up to you as that will change with exactly what and how you are doing
I would think about something between these lines:
// Users
{
username, hashedPassword, // credentials
permissions: [], // for when you start using permissions
active, // never delete data, just set the flag to "false", if, by GDPR rules you need to delete, you can change the name to "DELETED BY GDPR" and still maintain all references
}
// Patients
{
name,
address: { street, street2, city, zipcode, country }, // for invoicing proposes
mobile, // so you send them an SMS 24h before saying their appointment is "tomorrow"
}
// Doctors
{
name,
weekAvailability: [], // days of the week that a doctor is available as they normally work in more than one clinique
active, // never delete data, just set the flag to "false", if, by GDPR rules you need to delete, you can change the name to "DELETED BY GDPR" and still maintain all references
}
// Logs
{
action, // for example, "save", "add", "change"...
entity, // the collection name that the change happened
originalEntry, // the full document before changes
newEntry, // the full document after changes
timestamp, // the exact time of the change
user, // ref to users
}
// TimeRegistrations
{
user, // ref to users
patient, // ref to patients
doctor, // ref to doctors
title, description, appointmentStart, durationInMinutes,
}
regarding the infrastructure ... create an API (REST or GRAPHQL, the one you're most comfortable with) so you can separate the business logic from the frontend right from the start
your frontend (maybe React, Angular, VueJs) should call a proxy (nodeJs server running aside the frontend) to make authentications and call the API so all you should do in the frontend to be something like
fetch('/api/doctors')
.then(res => res.toJson())
.then(json => {
this.doctorsList = json
})
same as for authentication os a user where you can easily make use of a library to provide you with a JWT and easily maintain user logged in and with the right set of permissions
First approach but not good in your case i.e. One collection,
//doctors
{
_id: "",
appointments: [] // all appointments there
}
Second will be better but note in NoSql collection totally depends on how you want to get the data. Two collections:
//doctors
{
_id: "SOMETHING",
name: "SOMETHING"
}
//appointments
{
_id: "SOMETHING",
doctorId: "", // ref of doctor collection
appointmentAt: "",
appointmentAtMilli: "",
}

How to improve performance on nested graphql connections when using pagination

I'm trying to implement some kind of a basic social network project. It has Posts, Comments and Likes like any other.
A post can have many comments
A post can have many likes
A post can have one author
I have a /posts route on the client application. It lists the Posts by paginating and shows their title, image, authorName, commentCount and likesCount.
The graphql query is like this;
query {
posts(first: 10, after: "123456") {
totalCount
edges {
node {
id
title
imageUrl
author {
id
username
}
comments {
totalCount
}
likes {
totalCount
}
}
}
}
}
I'm using apollo-server, TypeORM, PostgreSQL and dataloader. I use dataloader to get author of each post. I simply batch the requested authorIds with dataloader, get authors from PostgreSQL with a where user.id in authorIds query, map the query result to the each authorId. You know, the most basic type of usage of dataloader.
But when I try to query the comments or likes connection under each post, I got stuck. I could use the same technique and use postId for them if there was no pagination. But now I have to include filter parameters for the pagination. And there maybe other filter parameters for some where condition as well.
I've found the cacheKeyFn option of dataloader. I simply create a string key for the passed filter object to the dataloader, and it doesn't duplicate them. It just passes the unique ones to the batchFn. But I can't create a sql query with TypeORM to get the results for each first, after, orderBy arguments separately and map the results back to the function which called the dataloader.
I've searched the spectrum.chat source code and I think they don't allow users to query nested connections. Also tried Github GraphQL Explorer and it lets you query nested connections.
Is there any recommended way to achieve this? I understood how to pass an object to dataloader and batch them using cacheKeyFn, but I can't figure out how to get the results from PostgreSQL in one query and map the results to return from the loader.
Thanks!
So, if you restrict things a bit, this is doable. The restriction is to only allowed batched connections on the first page of results, e.g. so all the connections you're fetching in parallel are being done with the parameters. This is a reasonable constraint because it lets you do things like get the first 10 feed items and the first 3 comments for each of them, which represents a fairly typical use case. Trying to support independent pagination within a single query is unlikely to fulfil any real world use cases for a UI, so it's likely an over-optimisation. With this in mind, you can support the "for each parent get the first N children" use case with PostgreSQL using window.
It's a bit fiddly, but there are answers floating around which will get you in the right direction: Grouped LIMIT in PostgreSQL: show the first N rows for each group?
So use dateloader how you are with cacheKeyFn, and let your loader function recognise whether you can perform the optimisation (e.g. after is null and all other arguments are the same). If you can optimise, use a windowing query, otherwise do unoptimised queries in parallel as you would normally.

Select * for Github GraphQL Search

One of the advantage of Github Search v4 (GraphQL) over v3 is that it can selectively pick the fields that we want, instead of always getting them all. However, the problem I'm facing now is how to get certain fields.
I tried the online help but it is more convolution to me than helpful. Till now, I'm still unable to find the fields for size, score and open issues for the returned repository(ies).
That's why I'm wondering if there is a way to get them all, like Select * in SQL. Thx.
GraphQL requires that when requesting a field that you also request a selection set for that field (one or more fields belonging to that field's type), unless the field resolves to a scalar like a string or number. That means unfortunately there is no syntax for "get all available fields" -- you always have to specify the fields you want the server to return.
Outside of perusing the docs, there's two additional ways you can get a better picture of the fields that are available. One is the GraphQL API Explorer, which lets you try out queries in real time. It's just a GraphiQL interface, which means when you're composing the query, you can trigger the autocomplete feature by pressing Shift+Space or Alt+Space to see a list of available fields.
If you want to look up the fields for a specific type, you can also just ask GraphQL :)
query{
__type(name:"Repository") {
fields {
name
description
type {
kind
name
description
}
args {
name
description
type {
kind
name
description
}
defaultValue
}
}
}
}
Short Answer: No, by design.
GraphQL was designed to have the client explicitly define the data required, leading to one of the primary benefits of GraphQL, which is preventing over fetching.
Technically you can use GraphQL fragments somewhere in your application for every field type, but if you don't know which fields you are trying to get it wouldn't help you.

Use Facebook FQL to select the work information from the profile

I would like to get work place information of a user using FQL.
When I use the Graph API and get the User object, it contains work information, which is essentially a list of the work history. The list elements contain nodes of employer, location, description, etc...
The nodes appear to be pages internally. If I take the id of a node, e.g. from the employer, and use FQL to query a page with that page_id, I do get an object with corresponding information.
My question now is, how do I use FQL to get the same information without accessing the Graph API? What table stores the work-related information, for example how do I find all the page_id of the employers of a given user?
The reason I insist on using FQL only is performance. Of course I could access the Graph API for all the users in question and get the info that way, but I'm looking for an FQL-only solution.
You can get this information from FQL. Read the "user" table and look for the work field. The JSON data returned should be the same format as the one for Graph, i.e., the result is an array and each result should include an "employer" object with an "id" and "name" field.
You will need user_work_history or friends_work_history to access this field.