npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vennekilde/go-a2s-template

v0.0.3

Published

Go Nats template for AsyncAPI generator.

Downloads

3

Readme

go-a2s-template

Examples

Asyncapi Streetlights API

As a example, the AsyncAPI streetlights api has been generated and can be found here: Generated API for AsyncAPI Streetlights

API Interface

Publish

    endpoint := client.S().Example().Endpoint()
    
    msg := endpoint.NewEndpointPubMsg()
    msg.Message.Payload.Text = "Hello World"
    
    err = endpoint.Publish(&msg, nil)
    if err != nil {
        t.Error(err)
    }

Subscribe

    endpoint := client.S().Example().Endpoint()

    sub, err := endpoint.Subscribe(
        func(msg *example.EndpointSubMsg) {
            // Do something with the received message.
            fmt.Println("%#v", msg)
        },
        nil,
    )
    if err != nil {
        panic(err)
    }
    defer sub.Unsubscribe()

Request

    endpoint := client.S().Example().Endpoint()

    requestMsg := endpoint.ReqMsg()
    requestMsg.Message.Payload.RequestText = "Hello World"
    
    replyMsg, err := endpoint.Request(&requestMsg, nil)
    if err != nil {
        t.Error(err)
    }
    fmt.Println("Received reply: %#v", replyMsg)

Reply

    sub, err := endpoint.Reply(
        func(request *example.EndpointReqMsg, reply *example.EndpointRepMsg) {
            // Do something with the received request.
            fmt.Println("Received reply: %#v", replyMsg)
    
            // Fill out reply with the response data.
            // The reply message will be sent once this function ends
            reply.Message.Payload.ReplyText = "World"
        },
        nil,
    )
    if err != nil {
        t.Error(err)
    }

Supported Transmission Clients

Feature | NATS (Default) | --|-- Channels | ✅ Parameters | ✅ Headers | ⚠️ No type generation, but can send any http.Header

Supported Message Codecs

Channel Properties

Property | NATS (Default) --|-- parameters | ✅ * | publish| ✅ | subscribe| ✅ | request| ✅ | reply| ✅ |

* Parameters are supported for basic types (string, integer, etc), but not supported for objects.

Message Properties

Property | NATS (Default) --|-- headers | ? | payload | ✅ |

Schema

The focus has been entirely on being able to transcode the messages, while none has been placed on the validation aspect or limiting the range a variable can take.

Schema Types

Type | JSON (Default) --|-- String | ✅ | Enum | ✅ | Boolean | ✅ | Integer | ✅ | Long | ✅ | Float | ✅ | Double | ✅ | Date | ✅ | DateTime | ✅ | Byte | ✅ | Binary | ✅ | Password | ✅ | Object | ✅ |

Schema Properties

Property | JSON (Default) --|-- required | ✅ | enum | ✅ | properties | ✅ | additionalProperties | ✅ | items | ✅ | OneOf | ⚠️ * | AllOf | ⚠️ * | AnyOf | ⚠️ * | multipleOf | ❌ | maximum | ❌ | exclusiveMaximum | ❌ | minimum | ❌ | exclusiveMinimum | ❌ | maxLength | ❌ | minLength | ❌ | pattern | ❌ | maxItems | ❌ | minItems | ❌ | uniqueItems | ❌ | maxProperties | ❌ | minProperties | ❌ | const | ❌ | if / then / else | ❌ | readOnly | ❌ | writeOnly | ❌ | patternProperties | ❌ | additionalItems | ❌ | propertyNames | ❌ | contains | ❌ | Not | ❌ |

* OneOf, AllOf & AnyOf only supports Object types. Additionally, there is no support for clashing field types, meaning that if two fields have the same name, but different types, the generated code will not function as intended, if it even compiles.Supported Schema Properties

Known limitations

JSON Codec limitations

Floating point precision

The GoJay JSON decoder appears to only be accurate down to the 6th and 15th decimal place for float32 and float64 respectively.

Likely, if you need better precision than this, you should probably not use floating points in the first place, but it is a weird issue that needs to be looked into and does make testing a little more tricky.

Go versions prior to 1.17 will experience issues with inaccurate encoding of floats due to https://github.com/golang/go/issues/36657.

How To Use

ag asyncapi.yaml ./tools/go-a2s-template -o gen/go-a2s-client --install --param moduleName=a2sclient --param modulePath=github.com/org/project

This will generate a Go module named github.com/org/project/a2sclient inside the folder gen/go-a2s-client relative to your current path

You can include the generated module in your code as any other Go module. An easy fast way would be to add replace github.com/org/project/a2sclient => ./gen/go-a2s-client to your go.mod

Parameters

Parameter | Type | Required | Default | Description --|--|--|--|-- moduleName | String | Yes | | Name that will be used to name the generated go module modulePath | String | Yes | | Source control path of the module without the name. e.g github.com/example/ perspective | String | No | | Which perspective to take when generating. See #Perspective section below. genProtocolCode | Boolean | No | true | Generate protocol specific code genTests | Boolean | No | true | Generate tests struct:genCodecs | Boolean | No | true | Enable or disable generation of encoders & decoders struct:genSchemas | Boolean | No | true | Enable or disable generation of schema structs struct:genMessages | Boolean | No | true | Enable or disable generation of message structs struct:messagesPath | String | No | message | Relative path to message structs. Does not change where messages are generated, only the import parts. struct:schemasPath | String | No | schema | Relative path to schema structs. Does not change where schemas are generated, only the import parts. go:genGoPGSQL | Boolean | No | true | Generate go-pg sql fields go:genAsModule | Boolean | No | true | GO: Generate as go module

Perspective

The default perspective will interpret the asyncapi file, such that if a channel is defined with a publish message. The generated client will have logic for publishing that message.

The same is true for if a channel contains a subscribe message, in which case the generated client will have logic for subscribing to the channel for receiving that message.

This logic can be reversed by setting the option perspective to reverse, effectively creating a mirror client to the none-reversed client.

You can use this to generate both the "sender" and the "receiver" from a single asyncapi file.

Generated API

AsyncAPI Spec Extensions

To de-clutter the generated API, you can specify a prefix and a version number, which will be used as a prefix for the channel.

Parameter | Type | Required | Default | Description --|--|--|--|-- x-version | String | No | | Name that will be used to name the generated go module x-prefix | String / Number | No | | Source control path of the module without the name. e.g github.com/example/

Example: The channel smartylighting/streetlights/1/0/action/{streetlightId}/turn/on can be defined as

action/{streetlightId}/turn/on:
  x-version: 1.0
  x-prefix: smartylighting/streetlights

Built in Error Handeling

To simplify exchange of error messages, this has been built into the client so you do not have to bloat your asyncapi spec with one of syntax and added logic to handle receiving multiple payload types.

Instead if both you and the recipient have enabled the feature, the publisher will add a header called GOA2S-LERR to indicate that it is capable of listening for published errors.

If the recipient also has the feature enable, it might respond to the reply channel with the header GOA2S-ISERR to indicate, that this reply is not a part of the standard message flow, but is instead an error and should be processed as such.

example



Template Development

Typescript Filters

Typescript is used in order to improve the maintainability of the filters and add better type awareness to the IDE.

The Typescript filters has to be transpiled to Javascript, as AsyncAPI does not understand native Typescript.

Typescript transpilation

The Typescript filters & hooks are transpiled by running the following command

make compile-filters