Basics of Go

JSON Parsing with Unmarshal

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Basics of Go

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

The "JSON Parsing with Unmarshal" 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 demonstrates the process of parsing and storing JSON data using the Unmarshal function from the json package. The Unmarshal function decodes the JSON-encoded data and saves the result in the provided value, which should be a pointer.


Transcript from the "JSON Parsing with Unmarshal" Lesson

>> So we need to parse JSON, okay? So fortunately Go includes JSON parsing and unparsing, because it includes HTTP, and also Go includes all the JSON management that we need. So for that we can go here, and now instead of printing the JSON, I need to do something else with it, okay?

So for working with JSON, I could create a new a new function if you want, the function is getting large, but let's start with here and then we can refactor it. So I need to talk with a JSON package. So you type json, lowercase, packages are typically lowercase, so lowercase json., and by the way, we have a problem using json, why?

Because that's the name of my variable as well. And in this case, my variable is overriding package names. So that's a tip. You shouldn't use variable names that are packages here, but there are solutions also to that, because you can add an alias to a package. But yeah, it's probably better to just change your variable, okay?

In fact, you will see that I won't actually even need this, okay? So, I'm going to delete the string, you will see that I don't need the string of the JSON. I will put that to the console. So, now I will try again json, and json, they have a couple of methods.

We have encoders and decoders, in case you wanna get deep into the process of encoding or decoding the JSON, but for simple things, you don't need to create a decoder or an encoder. Remember, is this a constructor? Here's a question for you, parentheses, question. NewDecoder, NewEncoder, what is that?

Is that a constructor? That's a factory. That's a factory. Remember, a factory is a design pattern. So the constructor is not a method or a function, a constructor is always when you use the type, and then you use curly braces, okay? So that's actually a factory. But what we have is the functions marshal and unmarshal.

Unmarshal will parse a JSON and will store that into an instance, into a value that you parse as an argument. So this is like the decoding. This is the one that is parsing, and it receives a slice of bytes. That's why I said that, I don't actually need to convert it into a string.

I can just take the bodyBytes that I have and unmarshal them. Marshall because had to do with the shaping, okay? It's using that definition of marshalling to marshal, it has to do with shape. So we are shaping the data that we have in JSON into another structure. And then I need to parse any, just any, it's a value.

Value is typically in Go what we used to say object or variable, or typically object in Java or JavaScript. When you say, that's an object, parse any object. We don't have the object name here, typically we say parse any value. Value is kind of anything in Go, okay?

So that's the term that we use in Go, value. So we think you'll parse a value, okay? So the idea is that it's not going to return me an object, in fact, if you look the Unmarshal, it returns only a possible error in case it couldn't decode that file.

And by the way, look at these, just completely off, but not off topic, but not related to this one. When I'm getting into the Unmarshal, remember this is Ctrl+click or Cmd+click if you're on a Mac, you're getting into the source code of Go. And this is the Unmarshal function within the JSON package, but the name of the file is actually decode.

Do we use the naming of the file anywhere? No, it's just how they organized the package. But the decode name we don't use it, it's not the function name, it's not the package name. We don't care about it, okay? Closing parenthesis. So I'm going to Unmarshal this, and, yeah, I received a possible error here, but not the data itself.

In this case, we need to parse the data as an argument. So, for example, I need to create first a variable that, I can call this my cryptoRate of type, Remember the package name, datatypes.Rate, okay? And then I need to kind of parse the variable like this. However, this is not gonna work as it is, why?

Because what happens when I parse a variable to a function?
>> It clones it.
>> It clones it. It creates a copy. So if I want to parse a variable and I want the function to change the contents of that variable, I need to parse the address of that variable.

Okay, makes sense? Then I should check if there is an error, it means that it's not a JSON, the JSON is not valid, something happened, the structure is not matching the JSON, something like that. So I should return nil and an error. Also, look at this, it's complaining that I shouldn't create new variables on left side of blah, blah, blah.

So what's going on here? That at the same code block, I already have another err variable. So I shouldn't use colon equals. If I want, I can reuse the same one, the same variable, but I shouldn't create a new one. It didn't happen before because we were in a different code block.

Remember block scope? If you're a JavaScript developer, this is similar to how let and const work with a block scope and not bar, bar is function scope. That's JavaScript, not Go, JavaScript. So if that works, it means that now we have our cryptoRate available. And that's a value that has the currency and the price.

But the problem is that, is the API matching my structure? So let's see this in action. So if I open Google Chrome and I use BTC here, this is the current structure.
>> There's nothing called price.
>> Yeah, there's nothing called price. I can open this here in the new file and format it as JSON, so we can see this better.

So let's compare that with my data type. I don't want that, I wanna send that to the right, there we are. So yeah, we don't have a currency, we don't have a price, so we have a problem, because I'm trying to convert that JSON into that structure and it's not working, okay?

So, and that's typically something normal. I typically receive data from a web service that is not mapping directly to my data model. So I need to make some kind of conversion here, okay? Makes sense? So I typically need to create another data type. Typically, it's part of the API, so not from part of my model.

So I need to create another file here for the data types of the API or the responses. Okay, so we can call these responses.go. Does that make sense? So package, what's the package? package api. And I need to somehow match this. Where is it? Here. But don't worry, you shouldn't be typing a lot because we will see another solution.

But anyway, let me start working with this.

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