go api webserver: total post request json data not taking as input - api

i made a api server to store the details of students. here the json keys are
StudentName
RollNo
Gender
Branch
when i send these values in post request , only Gender and branch values are storing.
code:
func PostStudentDetails(w http.ResponseWriter, r *http.Request) {
var student studentDb
err := json.NewDecoder(r.Body).Decode(&student)
if err != nil {
panic(err)
}
student.CreatedOn = time.Now()
id = id + 1
k := strconv.Itoa(id)
studentData[k] = student
j, err := json.Marshal(student)
if err != nil {
panic(err)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
w.Write(j)
log.Printf("%s", j)
log.Printf("%s", studentData)
}
i sent this json data in post request:
{
"StudentName": "test name",
"RollNo": "test number",
"Gender": "Male",
"Branch": "test "
}
but StudentName and RollNo are not stored
Response:
{"name":"","roll no":"","branch":"test ","gender":"Male","createdon":"2022-06-25T10:11:22.340365545Z"}
response log:
see this image log

Based on the json data you are sending to your app, can you please make sure that your Student struct has json tags that match the json payload.
So if you are sending in this json data
{
"StudentName": "test name",
"RollNo": "test number",
"Gender": "Male",
"Branch": "test "
}
Then your Student struct should have the json tags match the json field names. Notice how the part in backticks on each field is the same as the expected field name on the incoming payload.
type Student struct {
StudentName string `json:"StudentName,omitempty"`
RollNo string `json:"RollNo,omitempty"`
Gender string `json:"Gender,omitempty"`
Branch string `json:"Branch,omitempty"`
}

Related

How to fetch the particular field value from response body

This is the response body of post method
"body":
{
"id": 538,
"Fname": "abc",
"Lname": "Xyz",
"Type": {
"Type": "tryrtyr",
"createdBy": "ytyryr",
"createdDate": "2022-07-22T09:24:37.616+00:00",
"lastModifiedBy": "rtyryry",
"lastModifiedDate": "2022-07-22T09:24:37.616+00:00"
}
}
I tried to fetch the Id value but it is showing null value.
Fname, Lname are passing from excel file.
String jsonString = response.asString();
jsonString = response.asString();
List<Map<String, Object>> body = JsonPath.from(jsonString).get("");
Object Id = null;
for (Map<String, Object> item: body) {
if (item.get("Fname").toString().equals(Fname) &&
item.get("Lname").toString().equals(Lname)); {
Id = Integer.parseInt(item.get("id").toString());
}
}
System.out.println(Id);
Since the body is json object, not array, so you don't need a List here. I think you just need.
int id = response.jsonpath().getInt("id");

Is a Select() done against a key in the table's struct?

I have a database where one of the tables is managed through
type Token struct {
gorm.Model
Value string
User User
UserID uint
}
At some point, I am trying to retrieve all the elements in that table, but limited to only one field (Users). When doing the query without the Select(), I get everything as expected:
var tokens []Token
db.
Preload("User").
// Select("User").
Find(&tokens)
An extract from the output:
(...)
{
"ID": 27,
"CreatedAt": "2022-03-11T20:24:01.0505503+01:00",
"UpdatedAt": "2022-03-11T20:24:01.0505503+01:00",
"DeletedAt": null,
"Value": "admintoken",
"User": {
"ID": 27,
"CreatedAt": "2022-03-11T20:24:01.0521975+01:00",
"UpdatedAt": "2022-03-11T20:24:01.0521975+01:00",
"DeletedAt": null,
"UserName": "admin",
"UserType": {
"ID": 0,
"Name": "",
"UserID": 0
}
}
}
(...)
Since I only want to get the "User" object, I tried
var tokens []Token
db.
Preload("User").
Select("User").
Find(&tokens)
but now the output is empty.
What should the Select() be against?
To select all Users that have at least one token you could use the following query:
var users []User
db.Where("id IN (?)","SELECT DISTINCT(user_id) FROM tokens").Find(&users)
I don't think Preload is a good option since it would do 2 queries to retrieve the result, why do 2 queries if you can retrieve expected result in only 1 query
To retrieve users who has token code can be updated as below:
var users []User
db.Table("users").Select("users.id, users.name").Joins("inner join tokens on tokens.user_id = users.id").Find(&users)
rows, err := db.Table("users").Select("users.id, users.name").Joins("inner join tokens on tokens.user_id = users.id").Rows()
for rows.Next() {
...
}

Check for attribute value from JSON response

I am trying to validate the below conditions in the sample response
Based on subjectType attribute if it is either Person or Organization.
If subjectType is Person, check if it has a birthDate attribute
Sample response:
{
"subject": "ABC",
"subjectType": "Person",
"birthDate": "1951-03-07"
},
{
"subject": "ABC",
"subjectType": "Organization"
}
I tried this, but no luck.
def expected = {subjectType: 'Person', birthDate: '#present'}
def schema = { subjectType: '#? _ == "Person" || _ == "Organization"', birthDate: '#($.subjectType == "Person" ? "#present" : "#present")' }
match expected == schema
Any help is appreciated!
There are many answers that give you solutions, please start here:
https://stackoverflow.com/a/50350442/143475
Since I just came up with a new idea to solve this, I'm posting it below. Note that there is no right answer, and there are many, many ways to do what you want.
* def schemas =
"""
{
Person: { subject: '#string', subjectType: 'Person', birthDate: '#string' },
Organization: { subject: '#string', subjectType: 'Organization' }
}
"""
* def response = { "subject": "ABC", "subjectType": "Person", "birthDate": "1951-03-07" }
* def expected = schemas[response.subjectType]
* match response == expected
Also search slack overflow if you want to validate dates later.

Key Existence in JSON Object (Mule 4)

I need to check the existence of a particular keyword in a JSON object and based on that, create a string. My sample dataweave 2.0 code is given below:
%dw 2.0
output application/json
var arr = {
"ID": "100",
"ProdId": "Prod",
"ProdName": "ABC"
}
---
if (arr pluck $$ joinBy ';' contains "ProdId") == true
then (String: "Product") else
if (arr pluck $$ joinBy ';' contains "EmpId") == true
then (String: "Employee") else null
Based on the value of the variable, I need to have different String values. What change is needed above to work?
You can take advantage of the field existence operator ?:
%dw 2.0
output application/json
var o = {
"ID": "100",
"ProdId": "Prod",
"ProdName": "ABC"
}
---
if (o.ProdId?) (String: "Product") else
if (o.EmpId?) (String: "Employee") else null
You can solve your problem with pattern-matching by using the match operator as well:
%dw 2.0
output application/json
var o = {
"ID": "100",
"ProdId": "Prod",
"ProdName": "ABC"
}
---
"ProdId" match {
case "ProdId" -> "String": "Product"
case "EmpId" -> "String": "Employee"
else -> null
}
Here's the documentation:
if: https://docs.mulesoft.com/mule-runtime/4.3/dataweave-flow-control#control_flow_if_else
match: https://docs.mulesoft.com/mule-runtime/4.3/dataweave-pattern-matching
You also need to be aware that String is a type in DW, you must enclose it in quotes (" or ') to use as a field name.
I'm thinking about using the "keysOf" function (previously Object::keySet) and something like this:
%dw 2.0
output application/json
var arr = {
"ID": "100",
"ProdId": "Prod",
"ProdName": "ABC"
}
---
if (keysOf(arr) contains("ProdId" as Key)) "Product"
else if (keysOf(arr) contains("EmpId" as Key)) "Employee"
else "Not Recognized"
Note that "keysOf" returns an array of Key objects, not Strings.
EDIT:
A more dynamic approach can be this one:
%dw 2.0
output application/json
import firstWith from dw::core::Arrays
var arr = {
"ID": "100",
"ProdId": "Prod",
"ProdName": "ABC"
}
var myTypes = {
ProdId: "Product",
EmpId: "Employee"
}
var typeId = (keysOf(myTypes) firstWith (keysOf(arr) contains $)) as String
---
myTypes[typeId]

How to serialize c# object array into json object without an array

I want to use JsonConvert.Serialize in order to serialize a c# array class object into a json non-array object.
public list<employee> employees;
Output:
"{\"employees\":
{\"name\":\"Alex\",\"number\":\"25860340\"},
{\"name\":\"Tom\",\"number\":\"94085345\"}
}"
The format you have asked for in your question would not be valid JSON, because objects are not allowed to follow one another directly unless they are part of an array (see JSON.org). However, you could transform your employee list into a dictionary and serialize that instead, so long as you had a suitable key to use. One idea would be to use the employee number as a key, for example:
var employees = new List<Employee>
{
new Employee { name = "Alex", number = "25860340" },
new Employee { name = "Tom", number = "94085345" }
};
var obj = new
{
employees = employees.ToDictionary(e => e.number)
};
string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
Console.WriteLine(json);
That would give you this output, which is close to what you wanted:
{
"employees": {
"25860340": {
"name": "Alex",
"number": "25860340"
},
"94085345": {
"name": "Tom",
"number": "94085345"
}
}
}
If the employee number isn't actually unique, you could instead use each employee's position in the list as a key like this:
int i = 0;
var obj = new
{
employees = employees.ToDictionary(e => i++)
};
This would give you the following output instead:
{
"employees": {
"0": {
"name": "Alex",
"number": "25860340"
},
"1": {
"name": "Tom",
"number": "94085345"
}
}
}