Basics of Go

Mapping Between JSON and Go Struct

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Basics of Go

Check out a free preview of the full Basics of Go course

The "Mapping Between JSON and Go Struct" Lesson is part of the full, Basics of Go course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano creates a Go struct that aligns with the API's JSON response structure, using a JSON-to-Go converter tool. It emphasizes that if the property types in the struct do not match the JSON data, the Unmarshal function will raise an error.


Transcript from the "Mapping Between JSON and Go Struct" Lesson

>> So what I need is to create a structure that will match that thing. Do we need to create a structure with all the properties? Actually, no. I can just pick the properties that I want, okay? Which is okay. So I can just say type, we can call this C-E-X, CEX response, okay?

And then it's in a structure and then we can say, okay, let's say I want the, that's the pair, maybe I just want the price, the low, high, last, maybe we can take last, I don't know. And we can say, okay, I have the last that is a float64.

But we start having a couple of problems. First, last is lowercase l. Which is a problem if I want to export this to another back cache. Maybe in our case, we don't need to export it, because it's part of the API back cache. But you will know that that's the problem.

So do I need to match one by one the properties from the JSON and sometimes the JSON might include hyphens. That's JSON, even spaces. Don't do that at home. But you can do that in JSON. And of course, I cannot have a variable with that name. That makes sense.

So, if I want to match one by one, the properties we may have problems, we may encounter problems. So let me show you the solution. But to avoid, wasting or investing too much time doing that, let me show you a tool. There are a lot of tools. If you just google json to go struct.

You will see lots of tools. You can even ask maybe charge GPT or Google Bar to do this for you, where you paste the json, okay? In this case, the JSON structure the demo that this one, one JSON and it will show you and a structure at the right ready to copy and paste, okay?

Makes sense? It says if it allows inline type definition. What's that? Well, let's say that if the JSON, I wanna see if I can increase the font size a little bit like that. So if the JSON has another structure, for example, it says it has the currency. And the currency I'm just faking a JSON structure here.

And the currency is another object that has a name. Look what happens and the name is Bitcoin. Look what happens here the currency it's of type new structure. Those are inline type definitions. If I unclick that, the currency is a currency extract defined here at the bottom. So when you have structures like other objects or arrays within the JSON, thios tool will create all the code for that.

And also it can be the currency, let's say the currency is an array, so I can say an array, and now you can see it's a slice of currency. So it works pretty good, pretty okay. So let me remove that. Let's copy the structure, you can copy to clipboard.

And now let's paste it here. I have a typo here. I need to replace that autogenerated name. And now it looks like this. And you know everything, but not that part. So that's new. We haven't seen this. What that? What the back tick there with something there? Well, what is that?

So let's go full screen with this one. Properties in structures can contain metadata that is just a string, okay? For example, I can create an Id here. I'll say it's an integer. And I can open a string and say it will be auto automatic id, blah, blah, blah, blah, blah.

It's kind of a comment that you can add on properties. It's just a string. Will go do something with that? No, it's like a comment. However, back caches, libraries, frameworks, they can read using reflection APIs, those comments, labels. The json library can read metadata when it's marshaling or unmarshaling objects.

It can read that, and we can specify that metadata for that library. Reflection APIs lets you inspect types on the fly. So what it means is that when you use json column, it means I'm going to give you an instruction for the JSON library. Then I could add more things here for other libraries, okay?

It can be an object to database mapping library or things like that, that can create the SQL code for you, things like that. The thing is that JSON needs the the instruction that you're going to send to the library in double quotes. So that's why I'm not using double quotes there because then they have a quote problem.

So that's why typically we use backtick. That is another way to the final string in Go. So then we can use double quotes inside. So roughly, what you need is here, you're going to specify how is that property named in the JSON. So then you can map, instead of here, if you say, for example, well, first you can use capital letters now.

And if you have one property with a hyphen, with a space, or something like that, then you have a different thing on your side, and now it would work. So this is the mapping definition between the JSON and your Go structure, okay? That make sense? So we save this and now we know that that wasn't exactly correct.

So we actually need to create not a cryptoRate object. We need to create let's say a response object based on the CEX response. And that's what we're going to pass to the unmarshall function, okay? So I have just changed this line and also changed the variable that I'm sending.

That's typically what you're going to do. You're not going to unmarshal a JSON directly into your structure. You're going to create another structure that represents the JSON. Make sense? And the other thing that I need to change is the price. It's a fixed price. So now I need to get the price from their response.

The problem that I have at this point is that response does not exist. Does anyone know why? The declaration is there.
>> Scope code.
>> The scope, because that declaration is within the if so, I just need to move that declaration up. So then I could be using and getting from here the last, something like that.

Then it's complaining because the last it's float64. I'm expecting a float 64 and last is a string. You say, why? Well, that is because that's how the JSON is being defined. Last is a string. I don't know why, I didn't create the service. If you actually want the float, we have bid or ask, okay?

Those are floats. If not, we have to convert the string into that. And there is an strconv back cache that lets you convert the strings to other objects, but if not we can take bid or ask, Because they are actually floats or integers. In this case they are integers.

So if you look at that, I even type float. If I select B because it's an integer, why it's an integer, I don't know. It's part of the service. If I press return, it will actually add me automatically, the float64 converter function. Okay, make sense? Yeah, well, actually, maybe it's not an integer.

Maybe it was dot 0 and we don't see the dot 0. So if that's the case because ask is a float, B, no, because maybe it was just dot 0. So maybe I can go and change this into float64. I would say, no, you know what? The marshall, that's a float.

Even if in the current example, it was an integer, I know it's a float. So you can change that. And then I don't need the converter.
>> Is there a reason that you can't change that data type in that structure, right there? Like you changed it from an intuitive float64?

Is there a reason that you can't just-
>> What the reason is that, you write this? You say, well, I didn't write it. Well actually we use a tool to generate that. So the tool based on the current example make the automatic decision that that's an integer. But maybe it was just because of the JSON we took as a sample.

If I change this, it's going to say, no, no, it's a float. So the example that I, maybe I go again to the same URL I refresh. And maybe I get a different value. Look at this bid now has a decimal. So we had that luck and we took just one json where it was an integer.

And yeah, that automatic tool thought that it's always an integer, but it wasn't the case. So yeah, you can go and change it. Of course, if you change that with a different type, completely different type you say, this is an array in a slice. And then it's not an array in the JSON, it will give you an error when you are unmarshaling.

It says, no, I cannot match the structure.
>> But you can't just change one of those strings to a float64, because it would give you an error?
>> It will throw an error on the unmarshal operation, yeah. Okay, make sense? So let's see. If I run this, I'm getting something really weird here.

I don't like it. But because we're using print, maybe we should do something like if we don't have an error, I can talk with my format library and printf and say the rate for a value is another value. But the second value is going to be a float.

So if you want to float with some specific digits, you use, for example, 2f. That's a float with two decimal digits. And then I will take the rate.Currency as the first argument and rate.Price as the second argument. And if I run this, it says the rate for BTC is a lot of money.

$36,000 at the time of shooting this video. And also I can end this with a backhand, so that's for a new line, \n, so we don't have that, present symbol you see there, that means that there was no new line. So now if I run this, I'm getting that.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now