Expand and Filter OData - odata

I am trying to build a GET request to only pull specific data but I am having problems with utilizing OData.
Objects pulled from the API looks like this:
{
"PostalCode": "48103",
"FranchiseId": 397,
"Franchise": {
"ConceptId": 1,
"CreatedDateTime": "2015-10-20T18:36:46.353",
"ModifiedDateTime": "2018-01-26T14:35:33.447",
"DeletedDateTime": null,
"DoingBusinessAs": "Appliance.inc",
"Status": "Active",
"IsOwned": true,
"FranchiseeName": "Appliance Inc - Ann Arbor, MI - MLY 1001",
"LicenseNumber": "ML89023",
"City": "Ann Arbor",
"StateAbbr": "MI",
"PostalCode": "48104",
"ContactFirstName": "Doug",
"ContactLastName": "Smith",
"Country": "United States"
}
},
I am doing this GET request to get that data:
#url#&$expand=Franchise&$select=FranchiseId, PostalCode
I am using &$expand=Franchise just because I need the "FranchiseeName" from Franchise object but I don't want to pull the rest of the data of that object.
How can I write the request so I only pull three fields: PostalCode, FranchiseId, FranchiseeName. The object should look something like this:
{
"PostalCode": "48103",
"FranchiseId": 397,
"FranchiseeName": "Appliance.inc"
}

I assume #url# is a placeholder for the OData URI to your entity, e.g. http://server/odata/entityName.
The following URL should get the data you need:
http://server/odata/entityName?$select=PostalCode,FranchiseId&$expand=Franchise($select=FranchiseeName)
That should return only the required data, but still having the same structure as the full data, e.g:
{
"PostalCode": "48103",
"FranchiseId": 397,
"Franchise": {
"FranchiseeName": "Appliance.inc"
}
}

Related

Does TypeORM have a way to search for all documents with an array containing a value?

My goal is to use an input array of strings (fake emails) as a search query for documents in my MongoDB database, which I am powering using TypeORM. This way if I want to search for documents using more than one email at a time, I can do that. Meaning I want to be able to feed in:
query = ["kim#gmail.com", "jim#gmail.com", "sarah#gmail.com"] and get 3 different documents where document one has kim#gmail.com as the attendee, jim#gmail.com is another document's attendee field, and sarah#gmail.com is the third document's attendee (or is among them).
I want to use an email as a query to search for and return all documents where the array field has the email in the array.
So as an example here is the results for the "get all documents" endpoint right now:
[
{
"_id": "6283d7ad706445dc33319bcb",
"hostUsername": "jack",
"hostEmail": "jack#outlook.com",
"meetingName": "nervous-fish-hautily-vetting",
"startTime": "2022-12-12T08:00:00.000Z",
"attendees": [
"kate#gmail.com",
"sawyer#gmail.com"
]
},
{
"_id": "6284235e662f7dfb073e2cbc",
"hostUsername": "jacob",
"hostEmail": "jacob#gmail.com",
"meetingName": "eager-fish-hautily-vetting",
"startTime": "2022-12-12T08:00:00.000Z",
"attendees": [
"kate#gmail.com",
"benjaminlinus#gmail.com"
]
},
{
"_id": "6283d7c3706445dc33319bcc",
"hostUsername": "richard",
"hostEmail": "richard#outlook.com",
"meetingName": "eager-cat-hautily-subtracting",
"startTime": "2022-12-12T08:00:00.000Z",
"attendees": [
"johnlocke#gmail.com",
"hurley#gmail.com"
]
},
{
"_id": "6283d82b706445dc33319bcd",
"hostUsername": null,
"hostEmail": "richard#outlook.com",
"meetingName": "nervous-cat-hautily-jumping",
"startTime": "1970-01-01T00:00:00.000Z",
"attendees": null
},
{
"_id": "6283d8af706445dc33319bce",
"hostUsername": null,
"hostEmail": "richard#outlook.com",
"meetingName": "eager-plant-ignorantly-jumping",
"startTime": "1970-01-01T00:00:00.000Z",
"attendees": null
}
]
I want to query the database with ["kate#gmail.com"] and get back the two results that have "kate#gmail.com" in the attendees field.
The closest solution (that doesn't work) is the one I found in this GitHub issue and also another close solution (that doesn't work) in this StackOverflow question
Here is me implementing those two suggestions:
import { In } from "typeorm";
async searchMeetingsByDetails(
attendees?: string[]
): Promise<IMeeting[]> {
console.log(attendees, 39);
const meetingsByAttendees = attendees
? await this.meetingRepository.find({
where: {
attendees: In([...attendees]),
},
})
: [];
return [
meetingsByAttendees,
].flat();
}
This gives me an empty array [] when the input is ["kate#gmail.com"] so if the In() thing worked, it would give results.
const meetings = await this.meetingRepository
.createQueryBuilder("meeting")
.where("meeting.attendees IN (:attendees)", {
attendees: [...attendees],
});
This one gives ERROR [ExceptionsHandler] Query Builder is not supported by MongoDB. TypeORMError: Query Builder is not supported by MongoDB.

Create OnlineMeeting in MS Graph with Call-in Info

I am building some utilities to automate aspects of Microsoft Teams at my company. One thing we are trying is automating scheduling/creation of Online Meetings under various circumstances. Overall this is working fine, but I can't figure out how to get / attach telephone call-in information for the calls we're creating.
Here's an example POST /app/onlineMeetings:
{
"meetingType": "meetNow",
"participants": {
"organizer": {
"identity": {
"user": {
"id": "<user-id>"
}
}
}
},
"subject": "Personal Room"
}
And here's what a typical response looks like:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#app/onlineMeetings/$entity",
"joinUrl": "<join-url>",
"subject": "Personal Room",
"isCancelled": false,
"meetingType": "MeetNow",
"accessLevel": "SameEnterprise",
"id": "<meeting-id>",
"audioConferencing": null,
"meetingInfo": null,
"participants": {
"organizer": {
"upn": "<user-name>",
"sipProxyAddress": "<user-name>",
"identity": {
}
},
"attendees": []
},
"chatInfo": {}
}
As you can see, the audioConferencing key is null. If a user accesses the joinUrl, they can join the call and audio conferencing information is displayed at that time -- but I can't figure out how to get it out in advance (e.g. to send in an email).
Also note that since this is not a VTC-enabled meeting, the id can't be used to issue a new GET request for additional information, as discussed here

Best Practice / Design Patterns for data reformat

My project is a micro-services that connect two major services, my project fetches data from one server, format the data, and then use the data to generate an XML file, and then upload the XML to another service. I'm just wondering if there is any design pattern for this kind of micro-services.
this is the JSON received from the backend server:
{
"employee_id": 100464,
"organization_id": 93,
"start_date": "2018-09-05",
"first_name": "Tom",
"departments": [
{
"id": 2761,
"name": "Sale",
"organization_id": 93
},
{
"id": 2762,
"name": "Product",
"organization_id": 93
}
],
"primary_department": {
"id": 2761,
"name": "Product",
"organization_id": 93
}
}
This is the data format I want for, so I need to do some data formatting:
{
"employee_id": 100464,
"organization_id": 93,
"first_name": "Tom",
"target_department": {
"department_id": 2761,
"name": "Product",
"organization_id": 93,
"is_primary_department": true
}
}
the logic to determine the target_department is
departments = hsh.delete :departments
primary_department = hsh.delete :primary_department
hsh[:target_department] = departments.select do |department|
department[:id] ==another_obj[:group_id]
end.first
hsh[:target_department][:is_home_department] = (hsh[:target_department][:id] == primary_department[:id])
hsh[:target_department][:department_id] = hsh[:target_department].delete :id
As you can see, I need to remove, rename, and reformat attributes and the structure of the data.
During the process, there are many potential issues: attributes not existed?
My question is what's the best practice for dealing with this issue from programming designing perspective?
I am using Rails, so any good gem or project is dealing with a similar issue?
I don't know about best practices, but this ought to do what you want.
{
"employee_id": 100464,
"organization_id": 93,
"start_date": "2018-09-05",
"first_name": "Tom",
"departments": [
{
"id": 2761,
"name": "Sale",
"organization_id": 93
},
{
"id": 2762,
"name": "Product",
"organization_id": 93
}
],
"primary_department": {
"id": 2761,
"name": "Product",
"organization_id": 93
}
}.with_indifferent_access.except(:start_date, :departments).transform_keys do |k|
k == 'primary_department' ? 'target_department' : k
end.tap do |hsh|
if hsh['target_department']
hsh['target_department']['is_primary_department'] = true
hsh['target_department']['department_id'] = hsh['target_department']['id']
hsh['target_department'].delete('id')
end
puts hsh
end
In console, this will return:
{
"employee_id"=>100464,
"organization_id"=>93,
"first_name"=>"Tom",
"target_department"=>{
"name"=>"Product",
"organization_id"=>93,
"is_primary_department"=>true,
"department_id"=>2761
}
}
BTW, in your example output, you show the target_department name as "aProduct". Is that a typo?
Working directly with json/xml type data programmatically is often tedious. I once worked at a company that did this EVERYWHERE and it was painful. I would suggest deserializing your data into an object graph representation. Also have a result class that can be constructed by querying/processing your input object graph. Then just serialize your result object back to json at the end.
You can likely find a built-in or open source solution for handling the serialization and deserialization for you.

Accessing Values in Deeply Nested Array - Ruby on Rails

I am using an API call which returns a JSON response. I want to access the data inside the response so I can create some nice display cards showing the info and pictures. Here is a snippet from the response, the response property is populated with about 20 objects I'll include just two for brevity:
{
"success": true,
"message": "",
"result": [
{
"MarketCurrency": "LTC",
"BaseCurrency": "BTC",
"MarketCurrencyLong": "Litecoin",
"BaseCurrencyLong": "Bitcoin",
"MinTradeSize": 1e-8,
"MarketName": "BTC-LTC",
"IsActive": true,
"Created": "2014-02-13T00:00:00",
"Notice": null,
"IsSponsored": null,
"LogoUrl": "https://i.imgur.com/R29q3dD.png"
},
{
"MarketCurrency": "DOGE",
"BaseCurrency": "BTC",
"MarketCurrencyLong": "Dogecoin",
"BaseCurrencyLong": "Bitcoin",
"MinTradeSize": 1e-8,
"MarketName": "BTC-DOGE",
"IsActive": true,
"Created": "2014-02-13T00:00:00",
"Notice": null,
"IsSponsored": null,
"LogoUrl": "https://i.imgur.com/e1RS4Hn.png"
},
In my Rails controller I'm using JSON.parse and I'm trying to turn it into an object with the Open struct option:
#markets = JSON.parse(markets.to_json, object_class: OpenStruct)
In my view I'll do this <%=#markets.class%> and it shows Array and not object. So I try this <%=#markets.size%> and it shows 1. If I do <%=#markets[0]['success']%> I would expect it to return true but it returns 'success'. So, I'm not understanding why the ostruct library isn't working like I would expect or how I can get to the objects stored in the result array. Any help is greatly appreciated!
You already have a JSON response, isn't needed to use to_json again, try just parsing that object, and then use the dot . to access its fields, as an OpenStruct object now then you can access them as methods:
require 'json'
a = '{
"success": true,
"message": "",
"result": [{
"MarketCurrency": "LTC",
"BaseCurrency": "BTC",
"MarketCurrencyLong": "Litecoin",
"BaseCurrencyLong": "Bitcoin",
"MinTradeSize": 1e-8,
"MarketName": "BTC-LTC",
"IsActive": true,
"Created": "2014-02-13T00:00:00",
"Notice": null,
"IsSponsored": null,
"LogoUrl": "https://i.imgur.com/R29q3dD.png"
}, {
"MarketCurrency": "DOGE",
"BaseCurrency": "BTC",
"MarketCurrencyLong": "Dogecoin",
"BaseCurrencyLong": "Bitcoin",
"MinTradeSize": 1e-8,
"MarketName": "BTC-DOGE",
"IsActive": true,
"Created": "2014-02-13T00:00:00",
"Notice": null,
"IsSponsored": null,
"LogoUrl": "https://i.imgur.com/e1RS4Hn.png"
}]
}'
b = JSON.parse(a, object_class: OpenStruct)
p b.success
# => true
After much debugging and some assistance, I was able to get it to work. The response from the API call was an array with one item. The item was a long string of the entire dataset.
In order to get the expected behavior of "true" when calling #markets.success, I first had to
raw_markets = JSON.parse(markets.to_json)
followed by
#markets = raw_markets.map do |market|
JSON.parse(market, object_class: OpenStruct)
Note: the variable markets holds the original api call:
markets = open('url-to-api')
After this I would get #markets.success = "true" and #markets.result[0] held the first result, #markets.result[1] held the second result, and so on.

Rest-Assured Get jsonPath when JSON key starts with number

How do i get name=status using json path ... problem here is key=2 is random number,,, is their any way to skip these random and read name
Am using rest assured ,,this is sample response on GET request
Response
{
"error": false,
"message": "",
"data": {
"2": {
"name": "No Status",
"protected": "1",
"id": "1",
"temporal_start": "0",
"temporal_end": "2147483647"
},
"3": {
"name": "Started",
"protected": "1",
"id": "2",
"temporal_start": "0",
"temporal_end": "2147483647"
},
}
}
my request code is
given()
.param("error", "false")
.when()
.get(URI)
.then()
.body("data.2.name", startsWith(No))
I've found a solution but it's not very elegant:
when().
get(URI).
then().
body("data.collect { it.value }.reverse()[0].name", equalTo("No Status")).
body("data.collect { it.value }.reverse()[1].name", equalTo("Status"));
Which can be simplified using root paths:
when().
get(URI).
then().
root("data.collect { it.value }.reverse()[%d].name").
body(withArgs("0"), equalTo("No Status")).
body(withArgs("1"), equalTo("Status"));
Explanation:
Since data is a JsonObject represented as a HashMap we run the collect method to return only the values of the Map as a List. Then we reverse the list since it seems like the last when running collect the resulting list will have the last value first. Then we get the first value from this list (data.2 in your example) and finally get the name.

Resources