How to implement non-blocking client in grpc go?

I want to run different remote procedure on different servers without waiting for a reply from server. and as a server completes the procedure I want to have reply at the client. Can it be possible to do with grpc golang?

I want to run different remote procedure on different servers without waiting for a reply from server. and as a server completes the procedure I want to have reply at the client. Can it be possible to do with grpc golang?

I want to implement a blockchain network and I want to ask different peers to execute a transaction but I don't want to wait until one peer provides the output of execution and then I move to other peer.

In other word I want to broadcast the execution of procedure and then have all the answers as execution is being done.

I tried the common methods for connecting client and server but it waits for the response from the server. it will increase the time when execution needs to be done on more peers.

9 Reasons Why We Switched from Python to Go

9 Reasons Why We Switched from Python to Go

This post will explain some of the reasons why we decided to leave Python behind and make the switch to Go. Switching to a new language is always a big step, especially when only one of your team members has prior experience with that language.

Switching to a new language is always a big step, especially when only one of your team members has prior experience with that language. Early this year, we switched primary programming language from Python to Go. This post will explain some of the reasons why we decided to leave Python behind and make the switch to Go.

Reasons to Use Go

Reason 1 — Performance

Go is extremely fast. The performance is similar to that of Java or C++. For our use case, Go is typically 30 times faster than Python. Here’s a small benchmark game comparing Go vs Java.

Reason 2 — Language Performance Matters

For many applications, the programming language is simply the glue between the app and the database. The performance of the language itself usually doesn’t matter much.

Stream, however, is an API provider powering the feed infrastructure for 500 companies and more than 200 million end users. We’ve been optimizing Cassandra, PostgreSQL, Redis, etc. for years, but eventually, you reach the limits of the language you’re using.

Python is a great language but its performance is pretty sluggish for use cases such as serialization/deserialization, ranking and aggregation. We frequently ran into performance issues where Cassandra would take 1ms to retrieve the data and Python would spend the next 10ms turning it into objects.

Reason 3 — Developer Productivity & Not Getting Too Creative

Have a look at this little snippet of Go code from the How I Start Go tutorial. (This is a great tutorial and a good starting point to pick up a bit of Go.)

package main

type openWeatherMap struct{}

func (w openWeatherMap) temperature(city string) (float64, error) {
	resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&q=" + city)
	if err != nil {
		return 0, err
	}

	defer resp.Body.Close()

	var d struct {
		Main struct {
			Kelvin float64 `json:"temp"`
		} `json:"main"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
		return 0, err
	}

	log.Printf("openWeatherMap: %s: %.2f", city, d.Main.Kelvin)
	return d.Main.Kelvin, nil
}

If you’re new to Go, there’s not much that will surprise you when reading that little code snippet. It showcases multiple assignments, data structures, pointers, formatting and a built-in HTTP library.

When I first started programming I always loved using Python’s more advanced features. Python allows you to get pretty creative with the code you’re writing. For instance, you can:

  • Use MetaClasses to self-register classes upon code initialization
  • Swap out True and False
  • Add functions to the list of built-in functions
  • Overload operators via magic methods

These features are fun to play around with but, as most programmers will agree, they often make the code harder to understand when reading someone else’s work.

Go forces you to stick to the basics. This makes it very easy to read anyone’s code and immediately understand what’s going on.

Note: How “easy” it is really depends on your use case, of course. If you want to create a basic CRUD API I’d still recommend Django + DRF, or Rails.

Reason 4 — Concurrency & Channels

As a language, Go tries to keep things simple. It doesn’t introduce many new concepts. The focus is on creating a simple language that is incredibly fast and easy to work with. The only area where it does get innovative is goroutines and channels. (To be 100% correct the concept of CSP started in 1977, so this innovation is more of a new approach to an old idea.) Goroutines are Go’s lightweight approach to threading, and channels are the preferred way to communicate between goroutines.

Goroutines are very cheap to create and only take a few KBs of additional memory. Because Goroutines are so light, it is possible to have hundreds or even thousands of them running at the same time.

You can communicate between goroutines using channels. The Go runtime handles all the complexity. The goroutines and channel-based approach to concurrency makes it very easy to use all available CPU cores and handle concurrent IO — all without complicating development. Compared to Python/Java, running a function on a goroutine requires minimal boilerplate code. You simply prepend the function call with the keyword “go”:

package main

import (
	"fmt"
	"time"
)

func say(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}

}

func main() {
	go say("world")
	say("hello")
}

https://tour.golang.org/concurrency/1

Go’s approach to concurrency is very easy to work with. It’s an interesting approach compared to Node where the developer has to pay close attention to how asynchronous code is handled.

Another great aspect of concurrency in Go is the race detector. This makes it easy to figure out if there are any race conditions within your asynchronous code.

Here are a few good resources to get started with Go and channels:

Reason 5 — Fast Compile Time

Our largest micro service written in Go currently takes 6 seconds to compile. Go’s fast compile times are a major productivity win compared to languages like Java and C++ which are famous for sluggish compilation speed. I like sword fighting, but it’s even nicer to get things done while I still remember what the code is supposed to do:
Why We Switched from Python to Go

Reason 6 — The Ability to Build a Team

First of all, let’s start with the obvious: there are not as many Go developers compared to older languages like C++ and Java. According to StackOverflow, 38% of developers know Java, 19.3% know C++ and only 4.6% know Go. GitHub data shows a similar trend: Go is more widely used than languages such as Erlang, Scala and Elixir, but less popular than Java and C++.

Fortunately, Go is a very simple and easy to learn language. It provides the basic features you need and nothing else. The new concepts it introduces are the “defer” statement and built-in management of concurrency with “go routines” and channels. (For the purists: Go isn’t the first language to implement these concepts, just the first to make them popular.) Any Python, Elixir, C++, Scala or Java dev that joins a team can be effective at Go within a month because of its simplicity.

We’ve found it easier to build a team of Go developers compared to many other languages. If you’re hiring people in competitive ecosystems like Boulder and Amsterdam this is an important benefit.

Reason 7 — Strong Ecosystem

For a team of our size (~20 people) the ecosystem matters. You simply can’t create value for your customers if you have to reinvent every little piece of functionality. Go has great support for the tools we use. Solid libraries were already available for Redis, RabbitMQ, PostgreSQL, Template parsing, Task scheduling, Expression parsing and RocksDB.

Go’s ecosystem is a major win compared to other newer languages like Rust or Elixir. It’s of course not as good as languages like Java, Python or Node, but it’s solid and for many basic needs you’ll find high-quality packages already available.

Reason 8 — Gofmt, Enforced Code Formatting

Let’s start with what is Gofmt? And no, it’s not a swear word. Gofmt is an awesome command line utility, built into the Go compiler for formatting your code. In terms of functionality it’s very similar to Python’s autopep8. While the show Silicon Valley portrays otherwise, most of us don’t really like to argue about tabs vs spaces. It’s important that formatting is consistent, but the actual formatting standard doesn’t really matter all that much. Gofmt avoids all of this discussion by having one official way to format your code.

Reason 9 — gRPC and Protocol Buffers

Go has first-class support for protocol buffers and gRPC. These two tools work very well together for building microservices which need to communicate via RPC. You only need to write a manifest where you define the RPC calls that can be made and what arguments they take. Both server and client code are then automatically generated from this manifest. This resulting code is both fast, has a very small network footprint and is easy to use.

From the same manifest, you can generate client code for many different languages even, such as C++, Java, Python and Ruby. So, no more ambiguous REST endpoints for internal traffic, that you have to write almost the same client and server code for every time. .

Disadvantages of Using Golang

Disadvantage 1 — Lack of Frameworks

Go doesn’t have a single dominant framework like Rails for Ruby, Django for Python or Laravel for PHP. This is a topic of heated debate within the Go community, as many people advocate that you shouldn’t use a framework to begin with. I totally agree that this is true for some use cases. However, if someone wants to build a simple CRUD API they will have a much easier time with Django/DJRF, Rails Laravel or Phoenix.

Disadvantage 2 — Error Handling

Go handles errors by simply returning an error from a function and expecting your calling code to handle the error (or to return it up the calling stack). While this approach works, it’s easy to lose scope of what went wrong to ensure you can provide a meaningful error to your users. The errors package solves this problem by allowing you to add context and a stack trace to your errors.

Another issue is that it’s easy to forget to handle an error by accident. Static analysis tools like errcheck and megacheck are handy to avoid making these mistakes.

While these workarounds work well it doesn’t feel quite right. You’d expect proper error handling to be supported by the language.

Disadvantage 3 — Package Management

Go’s package management is by no means perfect. By default, it doesn’t have a way to specify a specific version of a dependency and there’s no way to create reproducible builds. Python, Node and Ruby all have better systems for package management. However, with the right tools, Go’s package management works quite well.

You can use Dep to manage your dependencies to allow specifying and pinning versions. Apart from that, we’ve contributed an open-source tool called VirtualGo which makes it easier to work on multiple projects written in Go.

Python vs Go

One interesting experiment we conducted was taking our ranked feed functionality in Python and rewriting it in Go. Have a look at this example of a ranking method:

{
	"functions": {
		"simple_gauss": {
			"base": "decay_gauss",
			"scale": "5d",
			"offset": "1d",
			"decay": "0.3"
		},
		"popularity_gauss": {
			"base": "decay_gauss",
			"scale": "100",
			"offset": "5",
			"decay": "0.5"
		}
	},
	"defaults": {
		"popularity": 1
	},
	"score": "simple_gauss(time)*popularity"
}

Both the Python and Go code need to do the following to support this ranking method:

  1. Parse the expression for the score. In this case, we want to turn this string “simple_gauss(time)*popularity” into a function that takes an activity as input and returns a score as output.
  2. Create partial functions based on the JSON config. For example, we want “simple_gauss” to call “decay_gauss” with a scale of 5 days, offset of 1 day and a decay factor of 0.3.
  3. Parse the “defaults” configuration so you have a fallback if a certain field is not defined on an activity.
  4. Use the function from step 1 to score all activities in the feed.

Developing the Python version of the ranking code took roughly 3 days. That includes writing the code, unit tests and documentation. Next, we’ve spent approximately 2 weeks optimizing the code. One of the optimizations was translating the score expression (simple_gauss(time)*popularity) into an abstract syntax tree. We also implemented caching logic which pre-computed the score for certain times in the future.

In contrast, developing the Go version of this code took roughly 4 days. The performance didn’t require any further optimization. So while the initial bit of development was faster in Python, the Go based version ultimately required substantially less work from our team. As an added benefit, the Go code performed roughly 40 times faster than our highly-optimized Python code.

Now, this is just a single example of the performance gains we’ve experienced by switching to Go. It is, of course, comparing apples to oranges:

  • The ranking code was my first project in Go
  • The Go code was built after the Python code, so the use case was better understood
  • The Go library for expression parsing was of exceptional quality

Your mileage will vary. Some other components of our system took substantially more time to build in Go compared to Python. As a general trend, we see that developing Go code takes slightly more effort. However, we spend much less time optimizing the code for performance.

Elixir vs Go — The Runner Up

Another language we evaluated is Elixir. Elixir is built on top of the Erlang virtual machine. It’s a fascinating language and we considered it since one of our team members has a ton of experience with Erlang.

For our use cases, we noticed that Go’s raw performance is much better. Both Go and Elixir will do a great job serving thousands of concurrent requests. However, if you look at individual request performance, Go is substantially faster for our use case. Another reason why we chose Go over Elixir was the ecosystem. For the components we required, Go had more mature libraries whereas, in many cases, the Elixir libraries weren’t ready for production usage. It’s also harder to train/find developers to work with Elixir.

These reasons tipped the balance in favor of Go. The Phoenix framework for Elixir looks awesome though and is definitely worth a look.

Conclusion

Go is a very performant language with great support for concurrency. It is almost as fast as languages like C++ and Java. While it does take a bit more time to build things using Go compared to Python or Ruby, you’ll save a ton of time spent on optimizing the code.

We have a small development team at Stream powering the feeds for over 200 million end users. Go’s combination of a great ecosystem, easy onboarding for new developers, fast performance, solid support for concurrency and a productive programming environment make it a great choice.

Stream still leverages Python for our dashboard, site and machine learning for personalized feeds. We won’t be saying goodbye to Python anytime soon, but going forward all performance-intensive code will be written in Go.

How to set up GraphQL with Golang: a deep dive from basics to advanced

How to set up GraphQL with Golang: a deep dive from basics to advanced

GraphQL has become a buzzword over the last few years after Facebook made it open-source. I have tried GraphQL with the Node.js, and I agree with all the buzz about the advantages and simplicity of GraphQL.

GraphQL has become a buzzword over the last few years after Facebook made it open-source. I have tried GraphQL with the Node.js, and I agree with all the buzz about the advantages and simplicity of GraphQL.

So what is GraphQL? This is what the official GraphQL definition says:

GraphQL is a query language for APIs and runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.
I recently switched to Golang for a new project I’m working on (from Node.js) and I decided to try GraphQL with it. There are not many library options with Golang but I have tried it with Thunder, graphql, graphql-go, and gqlgen. And I have to say that gqlgen is winning among all the libraries I have tried.

gqlgen is still in beta with latest version 0.7.2 at the time of writing this article, and it’s rapidly evolving. You can find their road-map here. And now 99designs is officially sponsoring them, so we will see even better development speed for this awesome open source project. vektah and neelance are major contributors, and neelance also wrote graphql-go.

So let’s dive into the library semantics assuming you have basic GraphQL knowledge.

Highlights

As their headline states,

GraphQL is a query language for APIs and runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.
I think this is the most promising thing about the library: you will never see map[string]interface{} here, as it uses a strictly typed approach.

Apart from that, it uses a Schema first Approach: so you define your API using the graphql Schema Definition Language. This has its own powerful code generation tools which will auto-generate all of your GraphQL code and you will just need to implement the core logic of that interface method.

I have divided this article into two phases:

  • The basics: Configuration, Mutations, Queries, and Subscription
  • The advanced: Authentication, Dataloaders, and Query Complexity

Phase 1: The Basics - Configuration, Mutations, Queries, and Subscriptions

We will use a video publishing site as an example in which a user can publish a video, add screenshots, add a review, and get videos and related videos.

mkdir -p $GOPATH/src/github.com/ridhamtarpara/go-graphql-demo/

Create the following schema in the project root:

type User {
    id: ID!
    name: String!
    email: String!
}

type Video {
    id: ID!
    name: String!
    description: String!
    user: User!
    url: String!
    createdAt: Timestamp!
    screenshots: [Screenshot]
    related(limit: Int = 25, offset: Int = 0): [Video!]!
}

type Screenshot {
    id: ID!
    videoId: ID!
    url: String!
}

input NewVideo {
    name: String!
    description: String!
    userId: ID!
    url: String!
}

type Mutation {
    createVideo(input: NewVideo!): Video!
}

type Query {
    Videos(limit: Int = 25, offset: Int = 0): [Video!]!
}

scalar Timestamp

Here we have defined our basic models and one mutation to publish new videos, and one query to get all videos. You can read more about the graphql schema here. We have also defined one custom type (scalar), as by default graphql has only 5 scalar types that include Int, Float, String, Boolean and ID.

So if you want to use custom type, then you can define a custom scalar in schema.graphql (like we have defined Timestamp) and provide its definition in code. In gqlgen, you need to provide marshal and unmarshal methods for all custom scalars and map them to gqlgen.yml.

Another major change in gqlgen in the last version is that they have removed the dependency on compiled binaries. So add the following file to your project under scripts/gqlgen.go.

// +build ignore

package main

import "github.com/99designs/gqlgen/cmd"

func main() {
	cmd.Execute()
}

and initialize dep with:

dep init

Now it’s time to take advantage of the library’s codegen feature which generates all the boring (but interesting for a few) skeleton code.

go run scripts/gqlgen.go init

which will create the following files:

gqlgen.yml — Config file to control code generation.

**generated.go **— The generated code which you might not want to see.

models_gen.go — All the models for input and type of your provided schema.

resolver.go — You need to write your implementations.

server/server.go — entry point with an http.Handler to start the GraphQL server.

Let’s have a look at one of the generated models of the Video type:

type Video struct {
	ID          string        `json:"id"`
	Name        string        `json:"name"`
	User        User          `json:"user"`
	URL         string        `json:"url"`
	CreatedAt   string        `json:"createdAt"`
	Screenshots []*Screenshot `json:"screenshots"`
	Related     []Video       `json:"related"`
}

Here, as you can see, ID is defined as a string and CreatedAt is also a string. Other related models are mapped accordingly, but in the real world you don’t want this — if you are using any SQL data type you want your ID field as int or int64, depending on your database.

For example I am using PostgreSQL for demo so of course I want ID as an int and CreatedAt as a time.Time. So we need to define our own model and instruct gqlgen to use our model instead of generating a new one.

type Video struct {
	ID          int       `json:"id"`
	Name        string    `json:"name"`
	Description string    `json:"description"`
	User        User      `json:"user"`
	URL         string    `json:"url"`
	CreatedAt   time.Time `json:"createdAt"`
	Related     []Video
}

// Lets redefine the base ID type to use an id as int
func MarshalID(id int) graphql.Marshaler {
	return graphql.WriterFunc(func(w io.Writer) {
		io.WriteString(w, strconv.Quote(fmt.Sprintf("%d", id)))
	})
}

// And the same for the unmarshaler
func UnmarshalID(v interface{}) (int, error) {
	id, ok := v.(string)
	if !ok {
		return 0, fmt.Errorf("ids must be strings")
	}
	i, e := strconv.Atoi(id)
	return int(i), e
}

func MarshalTimestamp(t time.Time) graphql.Marshaler {
	timestamp := t.Unix() * 1000

	return graphql.WriterFunc(func(w io.Writer) {
		io.WriteString(w, strconv.FormatInt(timestamp, 10))
	})
}

func UnmarshalTimestamp(v interface{}) (time.Time, error) {
	if tmpStr, ok := v.(int); ok {
		return time.Unix(int64(tmpStr), 0), nil
	}
	return time.Time{}, errors.TimeStampError
}

and update gqlgen to use these models like this:

schema:
- schema.graphql
exec:
  filename: generated.go
model:
  filename: models_gen.go
resolver:
  filename: resolver.go
  type: Resolver
models:
  Video:
    model: github.com/ridhamtarpara/go-graphql-demo/api.Video
  ID:
    model: github.com/ridhamtarpara/go-graphql-demo/api.ID
  Timestamp:
model: github.com/ridhamtarpara/go-graphql-demo/api.Timestamp

So, the focal point is the custom definitions for ID and Timestamp with the marshal and unmarshal methods and their mapping in a gqlgen.yml file. Now when the user provides a string as ID, UnmarshalID will convert a string into an int. While sending the response, MarshalID will convert int to string. The same goes for Timestamp or any other custom scalar you define.

Now it’s time to implement real logic. Open resolver.go and provide the definition to mutation and queries. The stubs are already auto-generated with a not implemented panic statement so let’s override that.

func (r *mutationResolver) CreateVideo(ctx context.Context, input NewVideo) (api.Video, error) {
	newVideo := api.Video{
		URL:         input.URL,
		Name:        input.Name,
		CreatedAt:   time.Now().UTC(),
	}

	rows, err := dal.LogAndQuery(r.db, "INSERT INTO videos (name, url, user_id, created_at) VALUES($1, $2, $3, $4) RETURNING id",
		input.Name, input.URL, input.UserID, newVideo.CreatedAt)
	defer rows.Close()

	if err != nil || !rows.Next() {
		return api.Video{}, err
	}
	if err := rows.Scan(&newVideo.ID); err != nil {
		errors.DebugPrintf(err)
		if errors.IsForeignKeyError(err) {
			return api.Video{}, errors.UserNotExist
		}
		return api.Video{}, errors.InternalServerError
	}
  
	return newVideo, nil
}

func (r *queryResolver) Videos(ctx context.Context, limit *int, offset *int) ([]api.Video, error) {
	var video api.Video
	var videos []api.Video

	rows, err := dal.LogAndQuery(r.db, "SELECT id, name, url, created_at, user_id FROM videos ORDER BY created_at desc limit $1 offset $2", limit, offset)
	defer rows.Close();
	
    if err != nil {
		errors.DebugPrintf(err)
		return nil, errors.InternalServerError
	}
	for rows.Next() {
		if err := rows.Scan(&video.ID, &video.Name, &video.URL, &video.CreatedAt, &video.UserID); err != nil {
			errors.DebugPrintf(err)
			return nil, errors.InternalServerError
		}
		videos = append(videos, video)
	}

	return videos, nil
}

and hit the mutation:

Ohh it worked…… but wait, why is my user empty 😦? So here there is a similar concept like lazy and eager loading. As graphQL is extensible, you need to define which fields you want to populate eagerly and which ones lazily.

I have created this golden rule for my organization team working with gqlgen:

GraphQL is a query language for APIs and runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.
For our use-case, I want to load Related Videos (and even users) only if a client asks for those fields. But as we have included those fields in the models, gqlgen will assume that you will provide those values while resolving video — so currently we are getting an empty struct.

Sometimes you need a certain type of data every time, so you don’t want to load it with another query. Rather you can use something like SQL joins to improve performance. For one use-case (not included in the article), I needed video metadata every time with the video which is stored in a different place. So if I loaded it when requested, I would need another query. But as I knew my requirements (that I need it everywhere on the client side), I preferred it to load eagerly to improve the performance.

So let’s rewrite the model and regenerate the gqlgen code. For the sake of simplicity, we will only define methods for the user.

type Video struct {
	ID          int       `json:"id"`
	Name        string    `json:"name"`
	Description string    `json:"description"`
	UserID      int       `json:"-"`
	URL         string    `json:"url"`
	CreatedAt   time.Time `json:"createdAt"`
}

So we have added UserID and removed User struct and regenerated the code:

go run scripts/gqlgen.go -v

This will generate the following interface methods to resolve the undefined structs and you need to define those in your resolver:

type VideoResolver interface {
	User(ctx context.Context, obj *api.Video) (api.User, error)
	Screenshots(ctx context.Context, obj *api.Video) ([]*api.Screenshot, error)
	Related(ctx context.Context, obj *api.Video, limit *int, offset *int) ([]api.Video, error)
}

And here is our definition:

func (r *videoResolver) User(ctx context.Context, obj *api.Video) (api.User, error) {
	rows, _ := dal.LogAndQuery(r.db,"SELECT id, name, email FROM users where id = $1", obj.UserID)
	defer rows.Close()
	
	if !rows.Next() {
		return api.User{}, nil
	}
	var user api.User
	if err := rows.Scan(&user.ID, &user.Name, &user.Email); err != nil {
		errors.DebugPrintf(err)
		return api.User{}, errors.InternalServerError
	}
	
	return user, nil
}

Now the result should look something like this:

So this covers the very basics of graphql and should get you started. Try a few things with graphql and the power of Golang! But before that, let’s have a look at subscription which should be included in the scope of this article.

Subscriptions

Graphql provides subscription as an operation type which allows you to subscribe to real tile data in GraphQL. gqlgen provides web socket-based real-time subscription events.

You need to define your subscription in the schema.graphql file. Here we are subscribing to the video publishing event.

type Subscription {
    videoPublished: Video!
}

Regenerate the code by running: go run scripts/gqlgen.go -v.

As explained earlier, it will make one interface in generated.go which you need to implement in your resolver. In our case, it looks like this:

var videoPublishedChannel map[string]chan api.Video

func init() {
	videoPublishedChannel = map[string]chan api.Video{}
}

type subscriptionResolver struct{ *Resolver }

func (r *subscriptionResolver) VideoPublished(ctx context.Context) (<-chan api.Video, error) {
	id := randx.String(8)

	videoEvent := make(chan api.Video, 1)
	go func() {
		<-ctx.Done()
	}()
	videoPublishedChannel[id] = videoEvent
	return videoEvent, nil
}

func (r *mutationResolver) CreateVideo(ctx context.Context, input NewVideo) (api.Video, error) {
	// your logic ...

	for _, observer := range videoPublishedChannel {
		observer <- newVideo
	}

	return newVideo, nil
}

Now, you need to emit events when a new video is created. As you can see on line 23 we have done that.

And it’s time to test the subscription:

GraphQL comes with certain advantages, but everything that glitters is not gold. You need to take care of a few things like authorizations, query complexity, caching, N+1 query problem, rate limiting, and a few more issues — otherwise it will put you in performance jeopardy.

Phase 2: The advanced - Authentication, Dataloaders, and Query Complexity

Every time I read a tutorial like this, I feel like I know everything I need to know and can get my all problems solved.

But when I start working on things on my own, I usually end up getting an internal server error or never-ending requests or dead ends and I have to dig deep into that to carve my way out. Hopefully we can help prevent that here.

Let’s take a look at a few advanced concepts starting with basic authentication.

Authentication

In a REST API, you have a sort of authentication system and some out of the box authorizations on particular endpoints. But in GraphQL, only one endpoint is exposed so you can achieve this with schema directives.

You need to edit your schema.graphql as follows:

type Mutation {
    createVideo(input: NewVideo!): Video! @isAuthenticated
}

directive @isAuthenticated on FIELD_DEFINITION

We have created an isAuthenticated directive and now we have applied that directive to createVideo subscription. After you regenerate code you need to give a definition of the directive. Currently, directives are implemented as struct methods instead of the interface so we have to give a definition.

I have updated the generated code of server.go and created a method to return graphql config for server.go as follows:

func NewRootResolvers(db *sql.DB) Config {
	c := Config{
		Resolvers: &Resolver{
			db: db,
		},
	}

	// Schema Directive
	c.Directives.IsAuthenticated = func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) {
		ctxUserID := ctx.Value(UserIDCtxKey)
		if ctxUserID != nil {
			return next(ctx)
		} else {
			return nil, errors.UnauthorisedError
		}
	}
	return c
}
rootHandler:= dataloaders.DataloaderMiddleware(
		db,
		handler.GraphQL(
			go_graphql_demo.NewExecutableSchema(go_graphql_demo.NewRootResolvers(db)
		)
	)
http.Handle("/query", auth.AuthMiddleware(rootHandler))

We have read the userId from the context. Looks strange right? How was userId inserted in the context and why in context? Ok, so gqlgen only provides you the request contexts at the implementation level, so you can not read any of the HTTP request data like headers or cookies in graphql resolvers or directives. Therefore, you need to add your middleware and fetch those data and put the data in your context.

So we need to define auth middleware to fetch auth data from the request and validate.

I haven’t defined any logic there, but instead I passed the userId as authorization for demo purposes. Then chain this middleware in server.go along with the new config loading method.

Now, the directive definition makes sense. Don’t handle unauthorized users in your middleware as it will be handled by your directive.

Demo time:

You can even pass arguments in the schema directives like this:

directive @hasRole(role: Role!) on FIELD_DEFINITION
enum Role { ADMIN USER }

Dataloaders

This all looks fancy, doesn’t it? You are loading data when needed. Clients have control of the data, there is no under-fetching and no over-fetching. But everything comes with a cost.

So what’s the cost here? Let’s take a look at the logs while fetching all the videos. We have 8 video entries and there are 5 users.

query{
  Videos(limit: 10){
    name
    user{
      name
    }
  }
}

Query: Videos : SELECT id, name, description, url, created_at, user_id FROM videos ORDER BY created_at desc limit $1 offset $2
Resolver: User : SELECT id, name, email FROM users where id = $1
Resolver: User : SELECT id, name, email FROM users where id = $1
Resolver: User : SELECT id, name, email FROM users where id = $1
Resolver: User : SELECT id, name, email FROM users where id = $1
Resolver: User : SELECT id, name, email FROM users where id = $1
Resolver: User : SELECT id, name, email FROM users where id = $1
Resolver: User : SELECT id, name, email FROM users where id = $1
Resolver: User : SELECT id, name, email FROM users where id = $1

Why 9 queries (1 videos table and 8 users table)? It looks horrible. I was just about to have a heart attack when I thought about replacing our current REST API servers with this…but dataloaders came as a complete cure for it!

This is known as the N+1 problem, There will be one query to get all the data and for each data (N) there will be another database query.

This is a very serious issue in terms of performance and resources: although these queries are parallel, they will use your resources up.

We will use the dataloaden library from the author of gqlgen. It is a Go- generated library. We will generate the dataloader for the user first.

go get github.com/vektah/dataloaden
dataloaden github.com/ridhamtarpara/go-graphql-demo/api.User

This will generate a file userloader_gen.go which has methods like Fetch, LoadAll, and Prime.

Now, we need to define the Fetch method to get the result in bulk.

func DataloaderMiddleware(db *sql.DB, next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		userloader := UserLoader{
			wait : 1 * time.Millisecond,
			maxBatch: 100,
			fetch: func(ids []int) ([]*api.User, []error) {
				var sqlQuery string
				if len(ids) == 1 {
					sqlQuery = "SELECT id, name, email from users WHERE id = ?"
				} else {
					sqlQuery = "SELECT id, name, email from users WHERE id IN (?)"
				}
				sqlQuery, arguments, err := sqlx.In(sqlQuery, ids)
				if err != nil {
					log.Println(err)
				}
				sqlQuery = sqlx.Rebind(sqlx.DOLLAR, sqlQuery)
				rows, err := dal.LogAndQuery(db, sqlQuery, arguments...)
				defer rows.Close();
				if err != nil {
					log.Println(err)
				}
				userById := map[int]*api.User{}

				for rows.Next() {
					user:= api.User{}
					if err := rows.Scan(&user.ID, &user.Name, &user.Email); err != nil {
						errors.DebugPrintf(err)
						return nil, []error{errors.InternalServerError}
					}
					userById[user.ID] = &user
				}

				users := make([]*api.User, len(ids))
				for i, id := range ids {
					users[i] = userById[id]
					i++
				}

				return users, nil
			},
		}
		ctx := context.WithValue(r.Context(), CtxKey, &userloader)
		r = r.WithContext(ctx)
		next.ServeHTTP(w, r)
	})
}

Here, we are waiting for 1ms for a user to load queries and we have kept a maximum batch of 100 queries. So now, instead of firing a query for each user, dataloader will wait for either 1 millisecond for 100 users before hitting the database. We need to change our user resolver logic to use dataloader instead of the previous query logic.

func (r *videoResolver) User(ctx context.Context, obj *api.Video) (api.User, error) {
	user, err := ctx.Value(dataloaders.CtxKey).(*dataloaders.UserLoader).Load(obj.UserID)
	return *user, err
}

After this, my logs look like this for similar data:

Query: Videos : SELECT id, name, description, url, created_at, user_id FROM videos ORDER BY created_at desc limit $1 offset $2
Dataloader: User : SELECT id, name, email from users WHERE id IN ($1, $2, $3, $4, $5)

Now only two queries are fired, so everyone is happy. The interesting thing is that only five user keys are given to query even though 8 videos are there. So dataloader removed duplicate entries.

Query Complexity

In GraphQL you are giving a powerful way for the client to fetch whatever they need, but this exposes you to the risk of denial of service attacks.

Let’s understand this through an example which we’ve been referring to for this whole article.

Now we have a related field in video type which returns related videos. And each related video is of the graphql video type so they all have related videos too…and this goes on.

Consider the following query to understand the severity of the situation:

{
  Videos(limit: 10, offset: 0){
    name
    url
    related(limit: 10, offset: 0){
      name
      url
      related(limit: 10, offset: 0){
        name
        url
        related(limit: 100, offset: 0){
          name
          url
        }
      }
    }
  }
}

If I add one more subobject or increase the limit to 100, then it will be millions of videos loading in one call. Perhaps (or rather definitely) this will make your database and service unresponsive.

gqlgen provides a way to define the maximum query complexity allowed in one call. You just need to add one line (Line 5 in the following snippet) in your graphql handler and define the maximum complexity (300 in our case).

rootHandler:= dataloaders.DataloaderMiddleware(
	db,
	handler.GraphQL(
		go_graphql_demo.NewExecutableSchema(go_graphql_demo.NewRootResolvers(db)),
		handler.ComplexityLimit(300)
  ),
)

gqlgen assigns fix complexity weight for each field so it will consider struct, array, and string all as equals. So for this query, complexity will be 12. But we know that nested fields weigh too much, so we need to tell gqlgen to calculate accordingly (in simple terms, use multiplication instead of just sum).

func NewRootResolvers(db *sql.DB) Config {
	c := Config{
		Resolvers: &Resolver{
			db: db,
		},
	}

	// Complexity
	countComplexity := func(childComplexity int, limit *int, offset *int) int {
		return *limit * childComplexity
	}
	c.Complexity.Query.Videos = countComplexity
	c.Complexity.Video.Related = countComplexity

	// Schema Directive
	c.Directives.IsAuthenticated = func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) {
		ctxUserID := ctx.Value(UserIDCtxKey)
		if ctxUserID != nil {
			return next(ctx)
		} else {
			return nil, errors.UnauthorisedError
		}
	}
	return c
}

Just like directives, complexity is also defined as struct, so we have changed our config method accordingly.

I haven’t defined the related method logic and just returned the empty array. So related is empty in the output, but this should give you a clear idea about how to use the query complexity.

Final Notes

This code is on Github. You can play around with it, and if you have any questions or concerns let me know in the comment section.

Learn More

Build a Basic App with Spring Boot and JPA using PostgreSQL

How to Install PostgreSQL on Ubuntu 18.04

An Introduction to Queries in PostgreSQL

GraphQL Tutorial: Understanding Spring Data JPA/SpringBoot

How To Manage an SQL Database

GraphQL with React: The Complete Developers Guide

GraphQL with Angular & Apollo - The Full-stack Guide

GraphQL: Learning GraphQL with Node.Js

Complete guide to building a GraphQL API

GraphQL: Introduction to GraphQL for beginners

Learn how to build an App with Vuejs and Golang

Learn how to build an App with Vuejs and Golang

In this tutorial, you’ll hearn how to build an app with Vuejs and Golang

I know, these two aren’t popular to be used along with each other. But, let’s try…

Background

Okay so first, let’s talk about the features these technologies provide.

Golang
  1. Binaries — The binaries are generated with all the dependencies built-in. Thus, you need not to install the runtimes to run the application.
  2. Static typing — The compiler takes care of the code when you are writing it and not only compile it. The type conversions and compatibility etc are taken care of.
  3. Concurrency — The best feature of Golang is that it has first-class support of concurrency built itself in the language.
  4. Standard library — The standard library is powerful enough that you mostly won’t need 3rd party libraries.
Vuejs
  1. Size — After gzipping it weighs only 18kB as compared to the minified jQuery which sizes to 29kB after gzipping.
  2. Readability — The code and syntax of Vuejs is very clear and simple.
  3. Documentation — It has thorough documentation which makes it fast and easy to learn.
  4. Reactivity — The data binding between HTML and Javascript is very fluid.
  5. Vue CLI 3 — It offers a lot of features that makes developers life easy. Just try it and you’ll love it.

Golang and Vuejs both are fast during runtime. Thus, making them work with each other provide a fast single page application.

Ok, let’s start.

Setting up directories

First, set up your directories like below. “LICENSE” and “README.md” for Git.

Now, in backend directory create a file server.go

For frontend, type the following in the terminal to create a new app Calculator,

                      vue create calculator

It will ask you to choose a preset. Choose the default one (babel, eslint).

Now this will be the folder structure.

The skeleton is ready!

Now, let’s see what we are going to build. It’s not a fancy app but will help you get started to build complex apps.

We are going to build a calculator in which you will enter two numbers, they will be grabbed by Vue frontend and sent to the Golang server using a POST request. The server will compute addition, multiplication, subtraction and division and send back the results using a POST request. The frontend will then render the results.

Build the backend

Golang is fast and the reason for it is the compiler, which doesn’t let you declare variables unless you use them. If you declare something or import any package you will have to use it. It is very strict about it. And also whatever you are going to do you have to tell the compiler beforehand like: if you want to grab the POST data, you have to declare the structure of the JSON data beforehand. This is a little tricky but worth the speed.

Coming to the code.

So, we’ll use the encoding/json and net/http packages. Then, we’ll declare the structures for the JSON data.

packages and the JSON data structures

Now, we’ll write a simple function to do the calculations. Here, we need to specify the return type explicitly.

process function

We need to write a function which will be called when we have to process the JSON data coming to the backend using POST request.

On line 33, we are declaring a JSON decoder to decode the incoming JSON data from therequest's body.

numsData and numsResData are the declared structures.

The incoming data is stored in numsData and is decoded on line 38.

Then we set up the ResponseWriter’s headers and then send the JSON response on line 47 and check for errors.

At last, the main function. Here we can define the HTTP routing. For every URL the respective function can be defined like on line 53. The backend server will run on PORT 8090.

The complete code is below:

package main

import (
"encoding/json"
"fmt"
"net/http"
)

type numbers struct {
Num1 float64 json:"num1"
Num2 float64 json:"num2"
}

type numsResponseData struct {
Add float64 json:"add"
Mul float64 json:"mul"
Sub float64 json:"sub"
Div float64 json:"div"
}

func process(numsdata numbers) (numsResponseData) {

var numsres numsResponseData
numsres.Add = numsdata.Num1 + numsdata.Num2
numsres.Mul = numsdata.Num1 * numsdata.Num2
numsres.Sub = numsdata.Num1 - numsdata.Num2
numsres.Div = numsdata.Num1 / numsdata.Num2

return numsres

}

func calc(w http.ResponseWriter, request *http.Request) {
decoder := json.NewDecoder(request.Body)

var numsData numbers
var numsResData numsResponseData

decoder.Decode(&amp;numsData)

numsResData = process(numsData)

fmt.Println(numsResData)

w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(numsResData); err != nil {
    panic(err)
}

}

func main() {
http.HandleFunc("/", calc)
http.ListenAndServe(":8090", nil)
}

Now let’s build the frontend

First cd into the frontend directory and install the dependencies using the below command.

   npm install --save bootstrap-vue bootstrap axios vee-validate

We’ll use axios for handling POST requests, vee-validate for validating the input form data and, bootstrap-vue for pretty interfaces.

In src/Calculator.vue we have to write the frontend part.

From line 17 to 25, we are defining the input boxes and labels to get the data.v-model is used to get the data in Vue.

The lines 30–35 define the UI for displaying the calculations and on line 43 a button, which will trigger the postreq() function which we will be defining next.

In the script tag, we write the javascript. First, we’ll import the requirements.

writing scripts tag

Lines 54–59 are the necessary stuff, importing axios and vee-validate.

Then, we’ll define the variables which we’ll use on lines 64–69. The data variable stores all the variables for the Calculator component.

In methods, all the functions are defined. We created postreq() function from where we are sending the POST request with JSON data to the url:http://localhost:8090/calc . Remember the calc function we created in server.go file? We are sending the JSON data there. After the data is sent, the response from the backend is stored in the result variable, from which we set the add, mul, sub and div variables which are binded to the HTML using {{ add }} etc. to show the result.

<template>
<div class="hello">
<!-- <h1>{{ msg }}</h1> -->

&lt;div&gt;
  &lt;h1 class="title"&gt;Calculator&lt;/h1&gt;
&lt;/div&gt;
&lt;hr&gt;

&lt;div&gt;
  &lt;b-container fluid&gt;
    &lt;b-row class="text-center"&gt;
      &lt;b-col cols="2" class="text-center"&gt;&lt;/b-col&gt;
      &lt;b-col cols="4" class="text-center"&gt;
      &lt;form&gt;
        
        &lt;div class="field"&gt;
          &lt;label class="label"&gt;First Number&lt;/label&gt;
          &lt;b-form-input name="num1" v-model="num1" v-validate="'required|digits'" class="input" type="text"&gt;&lt;/b-form-input&gt;
        &lt;/div&gt;

        &lt;div class="field" style="margin-top:13px;"&gt;
          &lt;label class="label"&gt;Second Number&lt;/label&gt;
          &lt;b-form-input name="num2" v-model="num2" class="input" v-validate="'required|digits'" type="text"&gt;&lt;/b-form-input&gt;
        &lt;/div&gt;
        
      &lt;/form&gt;
      &lt;/b-col&gt;

      &lt;b-col cols="4" class="text-left"&gt;
        &lt;div&gt;&lt;label class="label"&gt;Addition: {{ add }}&lt;/label&gt;&lt;/div&gt;
        &lt;div&gt;&lt;label class="label"&gt;Multiplication: {{ mul }}&lt;/label&gt;&lt;/div&gt;
        &lt;div&gt;&lt;label class="label"&gt;Subtraction: {{ sub }}&lt;/label&gt;&lt;/div&gt;
        &lt;div&gt;&lt;label class="label"&gt;Division: {{ div }}&lt;/label&gt;&lt;/div&gt;
      &lt;/b-col&gt;

    &lt;/b-row&gt;
  &lt;/b-container&gt;
&lt;/div&gt;

&amp;nbsp;
&lt;div&gt;
  &lt;b-button variant="primary" v-on:click="postreq()"&gt;Calculate&lt;/b-button&gt;  
&lt;/div&gt;

&amp;nbsp;
&lt;hr&gt;

</div>
</template>

<script>

import axios from 'axios';
import Vue from 'vue'
import VeeValidate from 'vee-validate'

/* eslint-disable */
Vue.use(VeeValidate)

export default {
name: 'Calculator',

data: function() {
return {
add: "", multi: "", sub: "", div: "",
num1: "", num2: ""
}
},

methods: {
postreq: function() {
var data = {"num1": parseFloat(this.num1), "num2": parseFloat(this.num2)}

  /*eslint-disable*/
  console.log(data) 
  /*eslint-enable*/

  axios({ method: "POST", url: "http://127.0.0.1:8090/calc", data: data, headers: {"content-type": "text/plain" } }).then(result =&gt; { 
      // this.response = result.data;
      this.add = result.data['add']
      this.mul = result.data['mul']
      this.sub = result.data['sub']
      this.div = result.data['div']

      /*eslint-disable*/
      console.log(result.data) 
      /*eslint-enable*/

    }).catch( error =&gt; {
        /*eslint-disable*/
        console.error(error);
        /*eslint-enable*/
  });
}

}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

Pretty simple huh? Yes, it is!

And that’s all we need to do. Just remember the points.

  • Write the server logic in Golang which will run on a separate PORT.
  • Build structures to hold the JSON data. You just can’t store them right away in a variable.
  • The Vuejs frontend will communicate to the server using API calls using GET or POST requests.
Run the App

The backend server can be run using

                        go run server.go

It will run on PORT 8090.

The frontend can be run using

                          npm run serve

Congratulations !!! Your app is ready.

The whole code is available on the Github repo.

Also, checkout an app Rocket Engine Designer, I built using Vuejs and Golang here.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

Build a Progressive Web App In VueJs

Build a CMS with Laravel and Vue

Beginner’s Guide to Vue.js

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Vue.js Tutorial: Zero to Sixty

Moving from NodeJS to Go

Building Modern Desktop Apps in Go

Google’s Go Essentials For Node.js / JavaScript Developers

The Complete Guide to Arrays in Go

Go Programming Language Tutorial | Golang Tutorial For Beginners | Go / Golang Crash Course

Golang Interfaces Tutorial with Examples for Developers

Golang Interfaces Tutorial with Examples for Developers

If you are new to Go language then, you may be heard or seen in the code about interface{} a lot in code snippets and tutorials. This can be very daunting seeing this at first. Interface implementation is one of the core concepts of Object-oriented programming language. If you have used Java, PHP, or Python then you might know what interface is and how it can be useful to build a scalable application.

Go Interface

An interface in Go is a type defined using a set of method signatures. The interface defines the behavior for similar type of objects.

For example, Here is an interface that defines the behavior for Geometrical shapes:

// Go Interface - `Shape`
type Shape interface {
	Area() float64
	Perimeter() float64
}

An interface is declared using the type keyword, followed by the name of the interface and the keyword interface. Then, we specify a set of method signatures inside curly braces.

Implementing an interface in Go

To implement an interface, you just need to implement all the methods declared in the interface.

Go Interfaces are implemented implicitly

Unlike other languages like Java, you don’t need to explicitly specify that a type implements an interface using something like an implements keyword.

Here are two Struct types that implement the Shape interface:

// Struct type `Rectangle` - implements the `Shape` interface by implementing all its methods.
type Rectangle struct {
	Length, Width float64
}

func (r Rectangle) Area() float64 {
	return r.Length * r.Width
}

func (r Rectangle) Perimeter() float64 {
	return 2 * (r.Length + r.Width)
}

// Struct type `Circle` - implements the `Shape` interface by implementing all its methods.
type Circle struct {
	Radius float64
}

func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}

func (c Circle) Perimeter() float64 {
	return 2 * math.Pi * c.Radius
}

func (c Circle) Diameter() float64 {
	return 2 * c.Radius
}

Using an interface type with concrete values

An interface in itself is not that useful unless we use it with a concrete type that implements all its methods.

Let’s see how an interface can be used with concrete values.

  • An interface type can hold any value that implements all its methods

package main

import (
    "fmt"
    "math"
)

func main() {
    var s Shape = Circle{5.0}
    fmt.Printf("Shape Type = %T, Shape Value = %v\n", s, s)
    fmt.Printf("Area = %f, Perimeter = %f\n\n", s.Area(), s.Perimeter())

    var s1 Shape = Rectangle{4.0, 6.0}
    fmt.Printf("Shape Type = %T, Shape Value = %v\n", s1, s1)
    fmt.Printf("Area = %f, Perimeter = %f\n", s1.Area(), s1.Perimeter())
}



# Output
Shape Type = main.Circle, Shape Value = {5}
Area = 78.539816, Perimeter = 31.415927

Shape Type = main.Rectangle, Shape Value = {4 6}
Area = 24.000000, Perimeter = 20.000000

  • Using Interface types as arguments to functions
package main

import (
    "fmt"
)

// Generic function to calculate the total area of multiple shapes of different types
func CalculateTotalArea(shapes ...Shape) float64 {
    totalArea := 0.0
    for _, s := range shapes {
        totalArea += s.Area()
    }
    return totalArea
}

func main() {
    totalArea := CalculateTotalArea(Circle{2}, Rectangle{4, 5}, Circle{10})
    fmt.Println("Total area = ", totalArea)
}



# Output
Total area =  346.7256359733385

  • Using Interface types as fields
package main

import (
    "fmt"
)

// Interface types can also be used as fields
type MyDrawing struct {
    shapes  []Shape
    bgColor string
    fgColor string
}

func (drawing MyDrawing) Area() float64 {
    totalArea := 0.0
    for _, s := range drawing.shapes {
        totalArea += s.Area()
    }
    return totalArea        
}

func main() {
    drawing := MyDrawing{
        shapes: []Shape{
            Circle{2},
            Rectangle{3, 5},
            Rectangle{4, 7},
        },
        bgColor: "red",
        fgColor: "white",
    }

    fmt.Println("Drawing", drawing)
    fmt.Println("Drawing Area = ", drawing.Area())
}



# Output
Drawing {[{2} {3 5} {4 7}] red white}
Drawing Area = 55.56637061435917

Interface values: How does an interface type work with concrete values?

Under the hood, an interface value can be thought of as a tuple consisting of a value and a concrete type:

// interface
(value, type)

Let’s see an example to understand more:


package main

import (
	"fmt"
)

func main() {
	var s Shape

	s = Circle{5}
	fmt.Printf("(%v, %T)\n", s, s)
	fmt.Printf("Shape area = %v\n", s.Area())

	s = Rectangle{4, 7}
	fmt.Printf("(%v, %T)\n", s, s)
	fmt.Printf("Shape area = %v\n", s.Area())
}


# Output
({5}, main.Circle)
Shape area = 78.53981633974483
({4 7}, main.Rectangle)
Shape area = 28

Checkout the output of the above program and notice how the variable s has information about the value as well as the type of the Shape that is assigned to it.

When we call a method on an interface value, a method of the same name on its underlying type is executed.

For example, in the above program, when we call the method Area() on the variable s, it executes the Area() method of its underlying type.