Communication between JavaScript and Go

GOX allows you to transfer values between JavaScript, Go and HTTP responses without reserializing them manually.

Pages, Actions and WebSocket use this system according to their own communication model:

AreaJavaScript to GoGo to the client
PagesThey do not receive arguments through this system.They build an HTTP response
ActionsThey get arguments.They return a result
WebSocketThey receive events and requestsThey send out events and responses

Although the three areas work with similar types, each transport determines how the result is delivered. gox.File returned by a Page is part of the HTTP response; the same type returned by an Action or sent by WebSocket becomes a File JavaScript.


Automatic conversion

GOX uses the types declared in Go to validate and convert the values received.

gox
type Profile struct {
    Name string
    Age  int
}

func GetProfile(name string, age int) gox.Action {
    return Profile{Name: name, Age: age}
}
js
const [profile, err] = await Actions.GetProfile("George", 30)

console.log(profile.Name)
console.log(profile.Age)

GOX converts the first argument to string, the second int and rebuilds the result as a Object JavaScript.

You do not need to parse JSON, convert numbers manually, or declare an additional schema.


Communication directions

Pages

The Pages respond to HTTP requests. They do not receive arguments sent directly from JavaScript via this system, but they can use different Go types to build the response.

gox
func Download() gox.Page {
    file, err := gox.NewFile(gox.FileConfig{
        Path: "documents/report.pdf",
    })
    if err != nil {
        return err
    }
    return file
}

A Page can respond with text, HTML, binary data, a stream or a gox.FileThe browser receives the result as an HTTP response.

Headers, cookies and the status code are administered by ctx.Response.

Actions

The Actions receive arguments from JavaScript and return a result:

js
const [result, err] = await Actions.UpdateProfile({
    Name: "George",
    Active: true,
})
gox
type Profile struct {
    Name   string
    Active bool
}

func UpdateProfile(profile Profile) gox.Action {
    return profile
}

The signature determines the amount, order and types expected. GOX validates the arguments before running the function and converts the result to a JavaScript-compatible representation.

WebSocket

WebSocket exchanges one or more values through events and requests:

js
socket.emit("greeting", "George")
gox
socket.On("greeting", func(name string) {
    socket.Emit("greeting", "Hola, "+name)
})

The same rules apply to sockets, groups and channels.


Types of values

GOX supports the following categories:

CategoryExamples in JavaScriptExamples in Go
Basic valuesstring, boolean, number, bigintstring, bool, int, float, big.Int
Structured valuesObject, Arraystruct, map, slice, array
DatesDatetime.Time
Nil valuesnullType that supports nil
Binary dataArrayBuffer, view, Blob[]byte, io.Reader
FilesFile, File[], FileListgox.File, []gox.File
HTMLHTMLElement, DocumentFragmentTemplate

The availability and final representation depend on the area used. See the corresponding reference:


Arguments and signatures

Actions and WebSocket assign the arguments by position.

gox
func Transfer(from string, to string, amount float64) gox.Action {
    ...
}
js
const [result, err] = await Actions.Transfer("usr_george", "usr_maria", 125.50)

The first argument is that from, the second to and the third amount.

GOX checks before running the function or handler:

  • The amount of arguments.
  • The order of values.
  • Compatibility with the declared types.
  • The conversion of the elements contained in struct, map, slice and array.

The parameters automatically provided by GOX, such as *gox.Context or the socket that originated a channel event, are not sent from JavaScript.


Representation by transport

The same type may be delivered differently according to the mechanism used.

Go valuePageActionWebSocket
Core valueHTTP response contentJavaScript valueArgument of the event
struct, map, slice, arrayHTTP response contentObject or ArrayObject or Array
TemplateHTML responseHTMLElement or DocumentFragmentHTMLElement or DocumentFragment
[]byteBinary bodyReadableStreamUint8Array
io.ReaderProgressive responseReadableStreamNot available as stream
gox.FileFile in HTTP responseFileFile
[]gox.FileNot availableFile[]File[]

This difference allows each area to preserve the natural behavior of its transport.


Conversion errors

If an argument cannot be converted to the expected type, GOX does not run the function or the handler.

gox
func UpdateAge(age int) gox.Action {
    ...
}
js
const [result, err] = await Actions.UpdateAge("invalid")

Actions deliver the problem through their error result. WebSocket communicates it through the event error corresponding. Errors produced when building a Page response are administered as errors of the HTTP request.


Integration with Go

GOX uses the signatures and the usual types of Go as a communication contract. struct describes a known structure, a map represents dynamic keys and a slice allows to receive or return a sequence.

Types like gox.File they keep information that cannot be represented by a basic value. Templates are part of the GOX syntax and allow to return HTML without manually building a type of transport.

It is not necessary to create exclusive models for communication when the application types already correctly describe the information.


Best practices

  • It uses specific types in the signatures of Actions and handlers.
  • Preference struct when the structure of a Object be known.
  • Use map only when the keys are dynamic.
  • It retains the same order between the arguments sent and the declared parameters.
  • Use gox.File when the name and type of the file are relevant.
  • It uses binary data for content without file identity.
  • It uses streams when the content is to be consumed progressively.
  • Avoid manually converting values that GOX can transfer directly.
  • Handle the errors according to the area used.

See also

Next step

Continue with Values to know the conversions of basic values, dates, structures and null values.

Values