The Go backend framework with superpowers

Overview

Encore - The Go backend framework with superpowers

https://encore.dev

Overview

Encore is a Go backend framework for rapidly creating APIs and distributed systems.

Encore works by using source code analysis to understand how your application fits together, and then uses that to provide many superpowers that radically improve the developer experience.

Read the complete documentation at encore.dev/docs.

Quick Start

Install

# macOS
brew install encoredev/tap/encore
# Linux
curl -L https://encore.dev/install.sh | bash
# Windows
iwr https://encore.dev/install.ps1 | iex

Create your app

encore app create my-app
cd my-app
encore run

Deploy

git push encore

Superpowers

Encore comes with tons of superpowers that radically simplify backend development compared to traditional frameworks:

  • A state of the art developer experience with unmatched productivity
  • Define services, APIs, and make API calls with a single line of Go code
  • Autocomplete and get compile-time checks for API calls
  • Generates beautiful API docs and API clients automatically
  • Instruments your app with Distributed Tracing, logs, and metrics – automatically
  • Runs serverlessly on Encore's cloud, or deploys to your own favorite cloud
  • Sets up dedicated Preview Environments for your pull requests
  • Supports flexible authentication
  • Manages your databases and migrates them automatically
  • Provides an extremely simple yet secure secrets management
  • And lots more...

Architecture

The code base is divided into several parts:

cli

The encore command line interface. The encore background daemon is located at cli/daemon and is responsible for managing processes, setting up databases and talking with the Encore servers for operations like fetching production logs.

parser

The Encore Parser statically analyzes Encore apps to build up a model of the application dubbed the Encore Syntax Tree (EST) that lives in parser/est.

For speed the parser does not perform traditional type-checking; it does limited type-checking for enforcing Encore-specific rules but otherwise relies on the underlying Go compiler to perform type-checking as part of building the application.

compiler

The Encore Compiler rewrites the source code based on the parsed Encore Syntax Tree to create a fully functioning application. It rewrites API calls & API handlers, injects instrumentation and secret values, and more.

Developing Encore and building from source

See DEVELOPING.md.

Comments
  • Cannot have paths /user/me and /user/:id/posts at the same time

    Cannot have paths /user/me and /user/:id/posts at the same time

    Currently, it's not possible to create the following endpoints at the same time:

    method=GET path=/user/:id
    method=GET path=/user/:id/posts
    

    Paths with parameters as the first part are also conflicting with any other non-parametrical paths:

    method=GET path=/users
    method=GET path=/:username/posts
    

    It'd be very nice to support these kinds of paths without conflicts, would it be possible?

    opened by ValeriaVG 8
  • Returning custom error messages on auth handlers

    Returning custom error messages on auth handlers

    Hi,

    I have a auth handler that looks something like this:

    //encore:authhandler
    func AuthHandler(ctx context.Context, token string) (auth.UID, *UserData, error) {
    	response, err := GetUserInternal(ctx, &GetUserInternalParams{
    		token: token,
    	})
    	if err != nil || response == nil {
    		log.WithError(err).Warning("Failed to authenticate user")
    		return "", nil, nil
    	}
    
    	if response.User.Status == model.UserStatus_Pending {
    		log.Warning("Authentication failed, user is still pending")
    		return "", nil, nil
    	}
    	if response.User.Status == model.UserStatus_Denied {
    		log.Warning("Authentication failed, user is denied")
    		return "", nil, nil
    	}
    
    	return auth.UID(strconv.FormatInt(response.User.ID, 10)), &UserData{
    		ID:       response.User.ID,
    	}, nil
    }
    

    I would like to be able to return custom unauthenticated messages for each of the three returns I have so a user knows why their auth failed. If I omit the error and return an empty string, the error message is something like "auth token missing", which is not very actionable for my users. If I do return the error, the 401 error turns into a 500 error with my message shown.

    I could mode this code to my endpoints instead, but it's a lot of duplicated code. I would like to be able to do something like returning a &errs.Error to customize the return code from an auth handler error.

    documentation 
    opened by Minivera 8
  • proposal: structured error responses

    proposal: structured error responses

    As discussed in #17 and elsewhere, Encore needs to provide the ability to control the error codes reported by the API as well as provide more structured data to callers.

    In summary, Encore would respond to external API call errors with an error in the form:

    {
       "code": "not_found",
       "message": "article not found",
       "details": {
            "article_id": 5
       }
    }
    

    In terms of API I propose the following design:

    package errs // import "encore.dev/beta/errs"
    
    // An Error is an error that provides structured information
    // about the error. It includes an error code, a message, and
    // optionally additional structured details about the error.
    //
    // Internally it captures an underlying error for printing
    // and for use with errors.Is/As and call stack information.
    //
    // To provide accurate stack information, users are expected
    // to convert non-Error errors into *Error as close to the
    // root cause as possible. This is made simple with Wrap.
    type Error struct {
    	Code    ErrCode    `json:"code"`
    	Message string     `json:"message"`
    	Details ErrDetails `json:"details"`
    	Meta    Metadata   `json:"-"` // not exposed to external clients
    }
    
    // Metadata represents structured key-value pairs, for attaching arbitrary
    // metadata to errors. The metadata is propagated between internal services
    // but is not exposed to external clients.
    type Metadata map[string]interface{}
    
    // New creates a new Error without wrapping another underlying error.
    // If code == OK it returns nil.
    func New(code ErrCode, msg string, metaPairs ...interface{}) error { /* ... */ }
    
    // NewWithDetails is like New but also sets Details.
    func NewWithDetails(code ErrCode, det ErrDetails, msg string, metaPairs ...interface{}) error { /* ... */ }
    
    // Wrap wraps the err, adding additional error information.
    // If err is nil it returns nil.
    //
    // If err is already an *Error its code, message, and details
    // are copied over to the new error.
    func Wrap(err error, msg string, metaPairs ...interface{}) error { /* ... */ }
    
    // WrapCode is like Wrap but also sets the error code.
    // If code is OK it reports nil.
    func WrapCode(err error, code ErrCode, msg string, metaPairs ...interface{}) error { /* ... */ }
    
    // Convert converts an error to an *Error.
    // If the error is already an *Error it returns it unmodified.
    // If err is nil it returns nil.
    func Convert(err error) error { /* ... */ }
    
    // Code reports the error code from an error.
    // If err is nil it reports OK.
    // Otherwise if err is not an *Error it reports Unknown.
    func Code(err error) ErrCode { /* ... */ }
    
    // Meta reports the metadata included in the error.
    // If err is nil or the error lacks metadata it reports nil.
    func Meta(err error) Metadata { /* ... */ }
    
    // Details reports the error details included in the error.
    // If err is nil or the error lacks details it reports nil.
    func Details(err error) ErrDetails { /* ... */ }
    
    // HTTPError writes structured error information to w using JSON encoding.
    // The status code is computed with HTTPStatus.
    //
    // If err is nil it writes:
    // 		{"code": "ok", "message": "", "details": null}
    func HTTPError(w http.ResponseWriter, err error) { /* ... */ }
    
    // HTTPStatus reports a suitable HTTP status code for an error, based on its code.
    // If err is nil it reports 200. If it's not an *Error it reports 500.
    func HTTPStatus(err error) int { /* ... */ }
    
    // ErrDetails is a marker interface for telling Encore
    // the type is used for reporting error details.
    //
    // We require a marker method (as opposed to using interface{})
    // to facilitate static analysis and to ensure the type
    // can be properly serialized across the network.
    type ErrDetails interface {
    	ErrDetails() // marker method; it need not do anything
    }
    
    // ErrCode is an RPC error code.
    type ErrCode int
    
    // These error codes are the same as the ones provided by gRPC for compatibility.
    const (
    	// OK indicates the operation was successful.
    	OK ErrCode = 0
    
    	// Canceled indicates the operation was canceled (typically by the caller).
    	//
    	// Encore will generate this error code when cancellation is requested.
    	Canceled ErrCode = 1
    
    	// Unknown error. An example of where this error may be returned is
    	// if a Status value received from another address space belongs to
    	// an error-space that is not known in this address space. Also
    	// errors raised by APIs that do not return enough error information
    	// may be converted to this error.
    	//
    	// Encore will generate this error code in the above two mentioned cases.
    	Unknown ErrCode = 2
    
    	// InvalidArgument indicates client specified an invalid argument.
    	// Note that this differs from FailedPrecondition. It indicates arguments
    	// that are problematic regardless of the state of the system
    	// (e.g., a malformed file name).
    	//
    	// Encore will generate this error code if the request data cannot be parsed.
    	InvalidArgument ErrCode = 3
    
    	// DeadlineExceeded means operation expired before completion.
    	// For operations that change the state of the system, this error may be
    	// returned even if the operation has completed successfully. For
    	// example, a successful response from a server could have been delayed
    	// long enough for the deadline to expire.
    	//
    	// Encore will generate this error code when the deadline is exceeded.
    	DeadlineExceeded ErrCode = 4
    
    	// NotFound means some requested entity (e.g., file or directory) was
    	// not found.
    	//
    	// Encore will not generate this error code.
    	NotFound ErrCode = 5
    
    	// AlreadyExists means an attempt to create an entity failed because one
    	// already exists.
    	//
    	// Encore will not generate this error code.
    	AlreadyExists ErrCode = 6
    
    	// PermissionDenied indicates the caller does not have permission to
    	// execute the specified operation. It must not be used for rejections
    	// caused by exhausting some resource (use ResourceExhausted
    	// instead for those errors). It must not be
    	// used if the caller cannot be identified (use Unauthenticated
    	// instead for those errors).
    	//
    	// Encore will not generate this error code.
    	PermissionDenied ErrCode = 7
    
    	// ResourceExhausted indicates some resource has been exhausted, perhaps
    	// a per-user quota, or perhaps the entire file system is out of space.
    	//
    	// Encore will generate this error code in out-of-memory and server overload
    	// situations, or when a message is larger than the configured maximum size.
    	ResourceExhausted ErrCode = 8
    
    	// FailedPrecondition indicates operation was rejected because the
    	// system is not in a state required for the operation's execution.
    	// For example, directory to be deleted may be non-empty, an rmdir
    	// operation is applied to a non-directory, etc.
    	//
    	// A litmus test that may help a service implementor in deciding
    	// between FailedPrecondition, Aborted, and Unavailable:
    	//  (a) Use Unavailable if the client can retry just the failing call.
    	//  (b) Use Aborted if the client should retry at a higher-level
    	//      (e.g., restarting a read-modify-write sequence).
    	//  (c) Use FailedPrecondition if the client should not retry until
    	//      the system state has been explicitly fixed. E.g., if an "rmdir"
    	//      fails because the directory is non-empty, FailedPrecondition
    	//      should be returned since the client should not retry unless
    	//      they have first fixed up the directory by deleting files from it.
    	//  (d) Use FailedPrecondition if the client performs conditional
    	//      Get/Update/Delete on a resource and the resource on the
    	//      server does not match the condition. E.g., conflicting
    	//      read-modify-write on the same resource.
    	//
    	// Encore will not generate this error code.
    	FailedPrecondition ErrCode = 9
    
    	// Aborted indicates the operation was aborted, typically due to a
    	// concurrency issue like sequencer check failures, transaction aborts,
    	// etc.
    	//
    	// See litmus test above for deciding between FailedPrecondition,
    	// Aborted, and Unavailable.
    	Aborted ErrCode = 10
    
    	// OutOfRange means operation was attempted past the valid range.
    	// E.g., seeking or reading past end of file.
    	//
    	// Unlike InvalidArgument, this error indicates a problem that may
    	// be fixed if the system state changes. For example, a 32-bit file
    	// system will generate InvalidArgument if asked to read at an
    	// offset that is not in the range [0,2^32-1], but it will generate
    	// OutOfRange if asked to read from an offset past the current
    	// file size.
    	//
    	// There is a fair bit of overlap between FailedPrecondition and
    	// OutOfRange. We recommend using OutOfRange (the more specific
    	// error) when it applies so that callers who are iterating through
    	// a space can easily look for an OutOfRange error to detect when
    	// they are done.
    	//
    	// Encore will not generate this error code.
    	OutOfRange ErrCode = 11
    
    	// Unimplemented indicates operation is not implemented or not
    	// supported/enabled in this service.
    	//
    	// Encore will generate this error code when an endpoint does not exist.
    	Unimplemented ErrCode = 12
    
    	// Internal errors. Means some invariants expected by underlying
    	// system has been broken. If you see one of these errors,
    	// something is very broken.
    	//
    	// Encore will generate this error code in several internal error conditions.
    	Internal ErrCode = 13
    
    	// Unavailable indicates the service is currently unavailable.
    	// This is a most likely a transient condition and may be corrected
    	// by retrying with a backoff. Note that it is not always safe to retry
    	// non-idempotent operations.
    	//
    	// See litmus test above for deciding between FailedPrecondition,
    	// Aborted, and Unavailable.
    	//
    	// Encore will generate this error code in aubrupt shutdown of a server process
    	// or network connection.
    	Unavailable ErrCode = 14
    
    	// DataLoss indicates unrecoverable data loss or corruption.
    	//
    	// Encore will not generate this error code.
    	DataLoss ErrCode = 15
    
    	// Unauthenticated indicates the request does not have valid
    	// authentication credentials for the operation.
    	//
    	// Encore will generate this error code when the authentication metadata
    	// is invalid or missing, and expects auth handlers to return errors with
    	// this code when the auth token is not valid.
    	Unauthenticated ErrCode = 16
    )
    
    opened by eandre 7
  • Add a JavaScript client to the code generation

    Add a JavaScript client to the code generation

    For older or client who do not use TypeScript, having a JavaScript client generated with code similar to the TypeScript client could be fairly useful. I have tried to implement that JavaScript client while staying as true to the coding style of the TypeScript client as possible. I have tested it locally and implemented the tests to make sure it generates the clients as expected. Indentation was a bit annoying in parts, but I think this works pretty great for what it is.

    Some alternative solutions:

    • For creating the TypeScript client, we could also use the TypeScript compiler to compile the TypeScript client to JavaScript instead.
    • For formatting, we could write teh code non-formatted and format it with a binary tool like Rome, which might work better than trying to ident it manually.

    Closes #371

    hacktoberfest 
    opened by Minivera 6
  • Support for Next.JS projects in generated clients

    Support for Next.JS projects in generated clients

    This commit adds support for generated Typescript clients to be compitable with Next.JS applications with the new --preset nextjs argument.

    The existing client was not compiatble as we where using namespaces to mimic the packages within the Encore application, however namespaces are somewhat depcreated and not all transpliers support them; the key one here being Babel (which Next.JS uses under the hood).

    When turned on the new --preset nextjs flag, therefore prevents the code generator from emitting namespaces, and instead it uses the package name as a prefix for generated types; such as $package_$struct.

    To make NextJS development easier, this flag also tells the TypeScript code generator to generate SWR wrappers for all API's, while maintaining the promise based functions if direct calls are still required (i.e. to perform actions).

    If the original api call was:

    const api = new Client()
    
    const rsp: Promise<Data> = api.MySvc.MyAPI("segment", { name: "bob" })
    

    The SWR wrapper will be:

    const api = new Client() // this needs to be a singleton for the application instance
    
    const rsp: SWRResponse<Data> = api.MySvc.useMyAPI("segment", { name: "bob" }, { refreshInternval: 1000 })
    
    opened by DomBlack 6
  • Proposal: Cron support

    Proposal: Cron support

    Summary

    We propose a simple mechanism for scheduling recurring tasks ("cron jobs").

    Motivation

    Encore today provides great support for building APIs that execute some business logic in response to some external trigger (a user taking an action in a frontend, a webhook being called, and so on). But there's no built-in way to internally trigger something to happen. While there are many such use cases that we want to support natively, the simplest and most flexible is support for cron jobs.

    Design

    Cron's original design is incredibly simple: specify when (or how frequently) a command should be executed. But when translated to building reliable systems, it turns out there are many nuances:

    • If execution fails, what failure mode is appropriate? Running the cron job more than once, or possibly not running it at all? (see The Two Generals' Problem)
    • What to do about partial failures? What if a cron job performs two tasks, and one succeeds but the other fails?
    • If a cron job is supposed to be launched every minute, and it takes more than a minute to complete, what should happen? Should two instances run concurrently? Should the second launch be skipped? Should the delay be measured from the stop time of the previous job, or from the start of it?

    And so on. What seemed simple at the surface turned out to be quite complex. At the same time we'd like to get a solution out sooner rather than later, so it's important that the design choices are (1) reasonable defaults, and (2) forward-compatible to support different trade-offs above, over time.

    To provide a portable implementation, we propose to start with a design that's based on the Kubernetes CronJob design. Specifically to make the following assumptions:

    • Jobs are expected to be idempotent, meaning it's possible the same job is run more than once
    • If a job is still running by the time the next job is supposed to start, another instance is started and both jobs run concurrently

    Configuration

    In order to define cron jobs, we propose to extend the encore.app configuration file (which is in JSON format) with a new cron key:

    "cron": [
    	{
    		// Required keys:
    		"endpoint": "service.Endpoint",
    		"schedule": "*/1 * * * *", // or "@hourly" etc
    
    		// Optional keys (with defaults):
    		"timezone": "UTC", // time zone the schedule is based on
    		"prod": true,      // whether to run in prod environments
    		"dev": true,       // whether to run in dev environments
    		"local": true,     // whether to run for local development
    	},
    	...
    ]
    

    Encore will validates all of these at compile-time. The endpoint must be a public or private endpoint which takes no parameters; that is, the signature is func Endpoint(context.Context) error or func Endpoint(context.Context) (*Response, error).

    Cron configuration will be updated at deployment time. For local development with encore run changes will be reflected immediately (with live reload). For Kubernetes deployments the cron job will be configured as a Kubernetes CronJob object.

    We believe this design strikes a good balance between supporting the most common use cases while being simple and portable. Adding support for additional use cases with different tradeoffs should be quite straightforward and backwards compatible by extending the configuration schema above.

    enhancement proposal 
    opened by eandre 6
  • `encore run` output control codes shown in Windows

    `encore run` output control codes shown in Windows

    After I start encore run, the formatting control codes are shown in Windows:

    ←[90m8:35PM←[0m ←[32mINF←[0m registered endpoint ←[36mendpoint=←[0mWorld ←[36mpath=←[0m/hello.World ←[36mservice=←[0mhello

    opened by kravlost 6
  • Improve the application structure documentation

    Improve the application structure documentation

    I had a very good discussion with @eandre on Slack regarding the difference between services and systems and I decided to write it down in the app-structure documentation page.

    I also noticed a broken link in the ORM doc, so I fixed that here as well.

    opened by Minivera 5
  • Add a how-to guide for using ent and atlas

    Add a how-to guide for using ent and atlas

    This is based on the discussion here: https://github.com/encoredev/encore/discussions/307, and my own usage of ent within my application. This is fairly early and there might be a better way of doing this with features of Encore I don't know yet.

    It's very easy to integrate a heavy ORM like ent with Encore if you're okay with tinkering a bit with scripts and commands. This guide shows one way of doing it, which could be expanded, but this seems to work really well on my end. We could also add a section for using only Atlas if it could be useful.

    Any feedback is very much appreciated!

    opened by Minivera 5
  • Proposal: Encore Messaging

    Proposal: Encore Messaging

    Encore Messaging Proposal

    Created: June 1, 2022 1:18 PM Last Updated: June 10, 2022 1:52 PM

    We’ve been looking into providing a cross-cloud encore abstraction for messaging. The feature set of messaging products across our supported cloud providers are somewhat different and the syntax is often overloaded, but the underlying semantics are relatively similar. The purpose of this proposal is to introduce an abstraction which is powerful enough to cover most use cases, while, where possible, remain cloud agnostic.

    Proposed design

    Overview

    flowchart LR
        Publisher1 --> Topic
    		Publisher2 --> Topic
    		Topic --> Subscription1
    		Topic --> Subscription2
    		Subscription1 -.-> DLQ1
    		Subscription2 -.-> DLQ2
    		Subscription1 --> Subscriber1
    		Subscription1 --> Subscriber2
    		Subscription2 --> Subscriber3
    		
    

    Messages are published by publishers to a Topic. The Topic forwards messages to Subscriptions where messages are queued until they’re consumed by a Subscriber. All published messages will be forwarded to all subscriptions. Each message on a subscription will be received by one subscriber. If the subscriber returns an error, the message will be retried MaxRetries times. After MaxRetries, the message will be forwarded to an opt-out Dead-letter Queue (DLQ) which can be manually inspected by a system admin.

    Message Definitions

    Messages consist of attributes, a body and metadata.

    Messages are defined using structs with field tags. Fields are marshalled as JSON and inserted into the Message body, unless they’re tagged with pubsub-attr, in which case they’re added as Message Attributes. The json tag can be used as usual for marshalling hints.

    type Email struct {
    	Language  string `pubsub-attr:"lang"` // Also marshalled as msg attribute
    	Recepient string `pubsub-attr:"recepient"` // Also marshalled as msg attribute
    	Priority  int    `pubsub-attr:"prio"`   
    	Subject   string
    	Body      string
    	Signature struct {
    		Name    string
    		Company string
    	}
    }
    

    It’s also possible to publish raw messages by using the RawMessage type. A RawMessage has a []byte body and a map of string attributes.

    var topic = pubsub.NewTopic[RawMessage]("rawtopic", nil)
    
    func SendRawMessage(ctx context.Context) error { 
    	msg := &RawMessage{
    		Attributes: map[string]string{
    			"header1": "value1",
    			"header2": "value2",
    		},
    		Body: []byte("This is a raw body")
    	}	
    	return topic.Publish(ctx, msg)
    }
    

    encore.CurrentRequest() is extended to include a MessageDatafield which contains Message specific properties like PublishTime, RetryAttempt and MessageId. Request.Type is set to PubSub if the current goroutine was initiated by a topic subscription.

    func ConsumeMessage(ctx context.Context, email *Email) error {
    	req := encore.CurrentRequest()
    	if msg != nil {
    		fmt.Printf("The current message was published at: %v", req.MessageData.PublishTime)
    	}
    }
    

    Topics and Subscriptions

    The Topic is the core entity of the messaging infrastructure. Topics accept messages from publishers which are then forwarded to Subscriptions. Subscriptions are message queues which store messages until they are consumed by one of their Subscribers.

    Topics are created as infrastructure resources and used to publish messages and create subscriptions. If they are uniquely consumed by one service, they should be declared in the package of the service. Otherwise it’s recommended to declare the Topic in a shared package. Topics should be typed using the Type Parameter.

    Create a topic named emails consisting of Email messages like so:

    var EmailTopic = pubsub.NewTopic[*Email]("emails", pubsub.TopicConfig{})
    

    Delivery Guarantees

    The Encore messaging API allows configuring a Delivery Guarantee per topic. The default DeliveryGuarantee is AtLeastOnce, meaning that each message on a Subscription is guaranteed to be delivered and acknowledged by a Subscriber at least once. The guarantee can be upgraded to ExactlyOnce, which is useful for e.g. email delivery, but will typically incur an extra cost from your cloud provider and limit throughput. A Topic can also be configured to guarantee ordered delivery of messages by setting Ordered to true. This guarantees that all messages sharing the same grouping key (a message attribute defined by GroupingKey) will be delivered in the order they were published.

    Create a Topic which delivers Email messages exactly once in the order they were published for a recipient like so:

    var EmailTopic = pubsub.NewTopic[*Email]("emails", pubsub.TopicConfig{
    	DeliveryPolicy: pubsub.DeliveryPolicy{
    		DeliveryGuarantee: pubsub.AtLeastOnce,
    		Ordered: true,
    		GroupingKey: "recipient"
    	}
    })
    

    The default TopicConfig is:

    TopicConfig{
    		DeliveryPolicy{
    			DeliveryGuarantee: pubsub.AtLeastOnce,
    			Ordered: False
    		}
    }
    

    Publishing Messages

    Messages are published by calling Publish on a Topic instance. Publish returns an id of the newly published message, or an error signalling the publish was unsuccessful.

    //encore:api public
    func SendMessage(ctx context.Context, email *Email) error {
    	id, err := EmailTopic.Publish(ctx, email)
    	if err != nil {
    		return errors.Wrap(err, "failed to publish message")
    	}
    	fmt.Printf("Published a message with id: %s", id)
    	return nil
    }
    

    Consuming Messages

    Message are consumed by Subscribers. A Subscription is created by using Topic.NewSubscription. The Subscription requires a subscription name (automatically provisioned by encore), a Subscriber handler and a SubscriptionConfig. The subscription name must be unique for thetopic, otherwise Encore will throw a compile error.

    Register a Subscriber (and create a Subscription named prio-email-sub), subscribing to messages with an attribute named priority set to 1, like so:

    var _ = EmailTopic.NewSubscription(
    	"email-sub", 
    	EmailService.SendEmail, // func(EmailService, context.Context, *Email) error
    	pubsub.SubscriptionConfig{},
    )
    
    func (e *EmailService) SendEmails(ctx context.Context, email *Email) error {
    	err := e.client.Send(email)
    	return err
    }
    

    The default SubscriptionConfig is:

    SubscriptionConfig{
    		RetryPolicy{
    			MinRetryDelay: 5 * time.Second,
    			MaxRetryDelay: 1 * time.Minute,
    			MaxRetries: 5,
    		}
    		AckDeadline: 30 * time.Second,
    		MessageRetention: 7 * time.Days,
    	},
    

    Acking, Nacking, Deadlettering

    A message is automatically Acked after a successful call to a subscriber. If a pubsub.UnrecoverableError is returned (based on errors.Is), the message will be forwarded directly to the deadletter topic. If any other error is returned, the message will be effectivelyNacked with a backoff delay. The exact implementation of this will depend on the provider. For e.g. AWS which doesn’t support backoffs, Encore modifies the visibility timeout to simulate exponential backoff.

    If a Message is not processed within the SubscriptionConfig.AckDeadline it will be returned to the Subscription and be re-delivered to a Subscriber. When the AckDeadline expires, the context used in the subscriber call will also be cancelled.

    If not consumed, Messages will be kept on the Subscription for the time specified bySubscriptionConfig.MessageRetention.

    Filtering

    A Filter can be defined for a Subscription. The Filter is a boolean expression operating on message Attributes. Supported operators are =, != ,&& and IN.

    Create a Subscription with a Filter selecting messages having a message Attribute named prio equalling 4 and lang is either en or es like so:

    var _ = EmailTopic.NewSubscription(
    	"email-sub", 
    	EmailService.SendEmail,
    	SubscriptionConfig{
    		Filter: `prio = 4 && lang IN ["en", "es"]`
    	},
    )
    

    Error Handling

    The RetryPolicy is applied when a subscriber returns an error while processing a message. The policy will backoff retries exponentially and is bounded by the MinRetryDelay and the MaxRetryDelay. If MaxRetries is exceeded, the message will be forwarded to a deadletter topic. Messages on this topic can be manually inspected and republished through the admin webapp.

    Create a Subscription which retries 10 times, starting with an initial delay of 5 seconds and backing off to a maximum of 5 minute before forwarding to the deadletter topic like so:

    var _ = EmailTopic.NewSubscription(
    	"prio-email-sub", 
    	EmailService.SendEmail,
    	SubscriptionConfig(
    		RetryPolicy: RetryPolicy{
    			MinRetryDelay: 5 * time.Second,
    			MaxRetryDelay: 5 * time.Minute,
    			MaxRetries: 10,
    		},
    		Filter: "prio=1"
    	),
    )
    

    A consumer can indicate that a message has an unrecoverable error by wrapping an error in pubsub.UnrecoverableError. This will tell encore to forward the message directly to the deadletter topic (without retrying). The following Subscriber will forward a message to the dead-letter topic without retry if the email recipient is invalid:

    func (e *EmailService) SendEmail(ctx context.Context, email *Email) error {
    	err := e.client.Send(ctx, email)
    	if errors.Is(err, emails.InvalidAddress) {
    		return pubsub.UnrecoverableError(err)
    	}
    	return err
    }
    

    Cloud Provider Support

    GCP implementation

    The GCP implementation would be based on GCP Pub/Sub. The Encore abstraction maps pretty well to the GCP implementation and we’re using similar language. GCP does however not support Ordered messages combined with ExactlyOnce delivery.

    AWS implementation

    The AWS implementation would be built on top of SNS and SQS. Messages would be published to an SNS topic, and a SQS would be created and attached to the Topic for each subscription. ExactlyOnce and Ordering is implemented through FIFO Topics and Queues. Retry backoff is implemented by modifying the visibility timeout of a message.

    Azure implementation

    The Azure implementation will be built on top of Service Bus Topics and Subscriptions. The Encore syntax matches the Azure functionality quite well. We’ll use FIFO subscriptions for OrderedDelivery and Duplicate Detection for ExactlyOnce delivery. Retry backoff is implemented by extending the lock for a Message.

    API Outline

    package pubsub
    
    // RawMessage is a special struct used to publish a raw
    // slice of bytes in the message body. Attributes can be used
    // to set custom message attributes
    type RawMessage struct {
    	Attributes map[string]string
    	Body []byte
    }
    
    // UnrecoverableError can be returned by a subscriber to
    // immediately drop or forward a messsage to a deadletter topic
    func UnrecoverableError(err error) UnrecoverableError
    
    // Subscriber is a function reference
    // The signature must be `func(context.Context, msg M) error` where M is either the
    // message type of the topic or RawMessage
    type Subscriber[T any] func(ctx context.Context, msg T) error
    
    type Subscription[T any] interface {}
    
    // Topic is the entry point for published messages
    type Topic[T any] interface{
    	// NewSubscription adds a handler to incoming messages on a topic.
    	// name is a unique name for the subscription and sub is a reference to a subscription handler.
    	// The SubscriptionConfig is used to configure filters, retries, etc.
    	NewSubscription(name string, sub Subscriber, cfg *SubscriptionConfig) *Subscription[T]
    
    	// Publish publishes messages. The result is the message id
    	// or an error signalling a publishing failure
    	Publish(ctx context.Context, msg T) (id string, err error)
    }
    
    type RetryPolicy struct {
    	// If MaxRetryDelay >= MinRetryDelay the first retry will be
    	// delayed MinRetryDelayed and then following retries will backoff
    	// exponentially until reaching the MaxRetryDelay
    	MinRetryDelay    time.Duration
    	MaxRetryDelay    time.Duration
    	// MaxRetries is used to control deadletter queuing logic
    	// n = -1 does not create a DLQ and retries infinitely
    	// n >=0 creates a DLQ and forwards a message to it after n retries
    	MaxRetries       int 
    }
    
    // DeliveryGuarantee is used to configure the delivery contract for a topic
    type DeliveryGuarantee int
    const (
    	// AtLeastOnce guarantees that a message for a subscription is delivered to 
      	// a subscriber at least once
    	AtLeastOnce DeliveryGuarantee = iota
    	// ExactlyOnce guarantees that a message for a subscription is delivered to 
      	// a subscriber exactly once
    	ExactlyOnce
    )
    
    // DeliveryPolicy configures how messages are deliverd from Topics
    type DeliveryPolicy struct {
    	// DeliveryGuarantee is used to configure the delivery guarantee of a Topic
    	DeliveryGuarantee DeliveryGuarantee
    	// Ordered should be set to true if messages should grouped by GroupingKey and 
    	// be delivered in the order they were published
    	Ordered bool
    	// GroupingKey is the name of the message attribute used to 
    	// partition messages into groups with guaranteed ordered 
    	// delivery.
    	// GroupingKey must be set if `Ordered` is true 
    	GroupingKey string
    }
    
    // TopicConfig is used when creating a Topic
    type TopicConfig struct {
    	// AWS does not support mixing FIFO SNS with standard SQS.
    	// Therefore, if one subscription is Ordered/OrderedExactlyOnce, 
    	// all others must be too. 
    	DeliveryPolicy *DeliveryPolicy
    }
    
    // SubscriptionConfig is used when creating a subscription
    type SubscriptionConfig struct {
    	// Filter is a boolean expresson using =, !=, IN, &&
    	// It is used to filter which messages are forwarded from the 
    	// topic to a subscription
    	Filter string
    
    	// AckDeadline is the time a consumer has to process a message
    	// before it's returned to the subscription
    	AckDeadline time.Duration
    
    	// MessageRetention is how long an undelivered message is kept 
    	// on the topic before it's purged
    	MessageRetention time.Duration
    
    	// RetryPolicy defines how a message should be retried when
    	// the subscriber returns an error
    	RetryPolicy *RetryPolicy
    }
    
    // NewTopic is used to declare a Topic. Encore will use static
    // analysis to identify Topics and automatically provision them
    // for you. 
    func NewTopic[T any](name string, cfg ...*TopicConfig) *Topic[T]
    
    
    package encore
    
    // Request is the existing metadata entity returned by
    // encore.CurrentRequest()
    type Request struct {
    	... // Previous fields
    	// MessageData contains fields specific to Messages
    	MessageData *MessageData
    }
    
    type MessageData struct {
    	// ID is the unique ID of the message assigned by the messaging service
    	ID string
    	// PublishTime is the time the message was first published
    	PublishTime time.Time
    	// DeliveryAttempt is a counter for how many times the messages
    	// has been attempted to be delivered
    	DeliveryAttempt int
    	// Error returned last time the message was attempted to be delivered
    	LastError error
    }
    
    

    Complete Example

    
    type Email struct {
    	Id string `pubsub-attr:"id" json:"-"`
    	From string
    	To string `pubsub-attr:"to"`
    	Subject string
      Body string
    }
    
    type EmailEvent struct {
    	Id string `pubsub-attr:"id"`
    	Type string `pubsub-attr:"type"`
    }
    
    emails := pubsub.NewTopic[*Email]("emails", &TopicConfig{})
    events := pubsub.NewTopic[*EmailEvent]("events", &TopicConfig{})
    
    var _ = emails.NewSubscription(
    	"email-sub", 
    	SendEmail, // Function generated by Encore
    	SubscriptionConfig(
    		DeliveryPolicy:  DeliveryPolicy {
    			DeliveryGuarantee: pubsub.OrderedExactlyOnce,
    			GroupingKey: "to",
    		}
    	)) 
    
    var _ = events.NewSubscription(
    	"event-sub", 
    	StoreEmailFailures, // Function generated by Encore
    	SubscriptionConfig(
    		Filter: pubsub.Filter(`
    			(type == "retry" && id <= 10000) || 
    			(type == "failed" && id > 10000)`),
    	),
    ) 
    
    type EmailService struct {
    	emailClient   EmailClient
    	storageClient StorageClient
    }
    
    func (s *EmailService) SendEmail(ctx context.Context, msg *Email) error {
    	if err := s.emailClient.Send(msg.Body); err != nil {
    		log.Error(err).Msg("failed to send email")
    		err =	events.Publish(ctx, &EmailEvent(msg.Body.Id, "failed"))
    		return pubsub.UnrecoverableError(err)
    	}
    	return events.Publish(ctx, &EmailEvent(msg.Body.Id, "success"))
    }
    
    func (s *EmailService) ScheduleEmail(ctx context.Context, email *Email) error {
    	return emails.Publish(ctx, email)
    } 
    
    func (s *EmailService) StoreEmailFailures(ctx context.Context, msg *EmailEvent) error {
    	err := s.storageClient.Store(event)
    	if err != nil {
    		return err
    	}
    	return nil
    }
    
    proposal 
    opened by ekerfelt 5
  • Improve local postgres setup

    Improve local postgres setup

    I've had a surprising failure trying to deploy my code with Postgres RowLevelSecurity(RLS) to encore cloud.

    Since locally the encore user was running with super user privileges, where row level security is ignored, I created a new user/role which each connection would switch to, so that RLS would work. Pushing this code to the cloud failed because the user running the migration isn't allowed to create users/roles.

    This PR changes the local setup to closer the cloud based behavior: a) there are two users now in the local setup: The postgres superuser and the encore 'create db' user b) the version of postgres is updated to allow users with 'create db' permission to install trusted extensions. That feature was introduced in postgres 13, the cloud is running 14, local env was running 11

    I don't expect this to be merged as this stage: ~~a) it's not the cleanest, the user creation code should only be run once, and not 'piggy backed' on the create db call.~~ b) the current migration path is: stop the cluster and delete the volumes, re-create the cluster with the encore cli so the permissions are in sync with the code. As is, it's not a hands-off experience, but rather breaking experience. The init scripts in the dockerfile won't run if a data directory is already present, so the encore user might or might not be there.

    for a) ~~I'd think a cleaner solution would be a thin wrapper around the postgres image that contains an initialization script ( as described in https://hub.docker.com/_/postgres) to create the encore user during the docker run phase of the cluster creation.~~ The code is there already: https://github.com/klemmster/encore-postgres, also manually pushed it to dockerhub. You seem to have a docker registry already, so I've created the PR to get the conversation rolling.

    Please let me know what your thoughts are on this topic or if there are open questions.

    opened by klemmster 5
  • [FEATURE-REQUEST] HTTP cache - RFC compliant with many other features

    [FEATURE-REQUEST] HTTP cache - RFC compliant with many other features

    Hello,

    I already wrote an HTTP cache system (called Souin) used by the caddy cache-handler module and roadrunner, compatible with Træfik, Tyk and many other reverse-proxies/API Gateway. It supports the RFC-7234, can partially cache graphQL request, invalidate using xkeys/ykeys like Varnish. It also implements the Fastly purge using the Surrogate-key header. It can store and invalidate a CDN (cloudflare, fastly, Akamai), and it supports the Cache-Status RFC directive. It implements two in-memory/fs storages (badger & nutsdb) and two distributed storages (olric & etcd) that are fully configurable. The keys can be tweaked (e.g. serve the same cached css for multiple domains) and we can change the Cache-Status name through the configuration and it support the ESI tags processing.

    Let me know your preference about that.✌️

    opened by darkweak 0
  • Add GraphQL Operation Tracing

    Add GraphQL Operation Tracing

    This commit adds the concept of a GraphQL operation event to our tracing implementation. This will allow the trace list view to show the name of the query, mutation or subscription to be shown rather than just the GraphQL endpoint name.

    To achieve this, we attempt to parse a raw endpoints request body as a GraphQL query document (using the same parser that gqlgen uses). If this parse succeeds, we assume that the endpoint is processing GraphQL and add the trace data

    Screenshots

    Before this change

    before

    After this change

    after

    opened by DomBlack 5
  • Add improved secrets management

    Add improved secrets management

    This adds much-improved secrets management to the Encore CLI. New functionality includes being able to specify per-environment secrets, listing the configured secrets and archiving secret values.

    opened by eandre 1
  • Support more PostgreSQL features

    Support more PostgreSQL features

    The underlaying driver used by encore to manage the is jackc/pgx which supports features such as copy from and batch queries. However, encore does not add support or forward the APIs for these features, something that would be nice to have.

    opened by melkstam 1
  • Add a way to export enum-like types to generated clients

    Add a way to export enum-like types to generated clients

    If you have a enum-like type

    type Permissions int
    
    const (
        PermAdmin Permissions = 1 << (iota + 1)
    
        PermListUsers Permissions = 1 << (iota +1)
        PermGetUser
        //. . .
    )
    

    and then generate a client encore gen client [project-id] -l [lang]

    the generated client won't contain any of the available constants, I suggest a way to have an encore-type comment to tell the compiler to include the constants inside a certain block.

    type Permissions int
    
    //encore:gen [lang]     <-------------------
    const (
        PermAdmin Permissions = 1 << (iota + 1)
    
        PermListUsers Permissions = 1 << (iota +1)
        PermGetUser
        //. . .
    )
    

    with the constants being included in all languages unless a language is specified.

    opened by shixzie 0
  • Add config.Duration type

    Add config.Duration type

    It would be nice to have a config.Duration type which parsed values into Go's standard time.Duration format. Ideally this would work identically to go's native duration parsing https://pkg.go.dev/time#ParseDuration.

    opened by Willyham 0
Releases(v1.11.0)
  • v1.11.0(Dec 8, 2022)

    Trace filtering is here!

    trace filter

    We've finally added filtering to the tracing dashboard, making it easier to find exactly what you're looking for when working on a big system.

    • You can now filter on duration, User ID, Trace ID, and X-Request-ID
    • Check it out for yourself in the web platform

    Bugfixes and other improvements

    Thank you for all your bug reports and feedback! Here are some improvements we've made lately:

    Thanks to our contributors!

    We rely on the community to improve Encore, and we're always amazed by your incredible support and encouragement. A massive thank you to Patryk Siemiński, Amr, Daniel Stocks, @Willyham, @klaidliadon, MaxD, @melkstam, Jakob Nordfeldt, Prasanna Balaji for your contributions and feedback!

    What’s next

    We're very close to releasing a huge upgrade to Encore's infrastructure provisioning system. This will give you more flexibility, and it will be simple to add specific requirements, e.g. deploying to existing Kubernetes clusters. We're also about to release built-in metrics dashboards and an upgraded secrets manager! – Remember to vote on your favorite feature on the roadmap!

    As always, if you have questions or feedback, tell us on Slack or post on the Community Forum.

    We’re excited to hear your feedback! ❤️

    Full Changelog: https://github.com/encoredev/encore/compare/v1.10.1...v1.11.0

    Source code(tar.gz)
    Source code(zip)
  • v1.10.1(Nov 4, 2022)

    Tracing is now sooo much better

    improved tracing view

    We've just released a much-improved trace view. Here's what you need to know:

    • Raw endpoints are now traced – including HTTP path, method, request/response bodies and headers.
    • Traces now come with a JSON viewer, letting you expand/collapse parts of the payload if it's unwieldy to view.
    • Remember to update before trying it out: encore version update

    Speed improvements to parser and tests

    To make Encore better for everyone with a very large code base, we've improved Encore's static analysis performance. The parser is now 5x faster!

    With Encore you run tests with encore test instead of go test. This is a wrapper that compiles the Encore app and then runs go test. It supports all the same flags that the go test command does. For bigger projects, we want to make sure this is snappy! – In the latest release, we've improved test speed 2x, both for local development as well as for CI/CD

    Bugfixes and other improvements

    We're always thankful when we get feedback and bug reports from anyone using Encore. Here are some improvements we've made lately, thanks to your input:

    • The metadata APIs that provide information about the current request also contains information about PubSub messages and Cron Job executions.
    • You can now override auth information for the current request inside tests.
    • Improved documentation for how to structure your Encore app (thanks to @Minivera!).

    Thanks to our contributors We rely on the community to improve Encore, and we continue to be surprised and humbled by your incredible support and encouragement. A massive thank you to @Minivera , Patryk Siemiński, Amr, Daniel Stocks, @Willyham, MaxD, @melkstam, Jakob Nordfeldt, Prasanna Balaji, and Juan Álvarez for your contributions and feedback!

    What’s next

    We're close to releasing a big upgrade to infrastructure provisioning, making it more flexible and easier for you to add specific requirements like deploying to existing Kubernetes clusters. We'll also soon release new observability and metrics capabilities. – Remember to vote on your favorite feature on the roadmap!

    As always, if you have questions or feedback, tell us on Slack or post on the Community Forum.

    We’re excited to hear your feedback! ❤️

    Full Changelog: https://github.com/encoredev/encore/compare/v1.9.3...v1.10.1

    Source code(tar.gz)
    Source code(zip)
  • v1.9.0(Oct 20, 2022)

    Or maybe just your application to start with.

    In this release, we're introducing a new config package that combines the power of CUE lang with the smooth Encore developer experience. It gives you both the type safety of Go, and the powerful flexibility of CUE. This lets you focus on writing your business logic, safe in the knowledge that Encore's compiler will prevent invalid configurations from ever reaching your production environment.

    To use it, you simply call config.Load[*MyConfigType]() and assign the returned instance of your config type to a package-level variable (Remember to first update with encore version update.)

    image

    As with many of Encore's features, config comes with isolated test support. This allows you to override configuration values on inside tests, without impacting any other concurrently running tests.

    For more information about Encore native config support, check out the docs.

    Bugfixes and other improvements

    We're always thankful when we get feedback and bug reports from anyone using Encore! Here are some improvements we've made lately, thanks to your input:

    • Added documentation to the encore.dev Go package to explain why those functions all panic, as well as including links to the underlying implementation (encoredev/encore.dev#11)
    • Fixed an issue with walking recursive types (#439)
    • Fixed an issue with the rendering of pointer types in the development dashboard (#440)
    • Improved the documentation by improving clarity on some pages, rewriting others and fixing various typos.

    Thanks to our contributors

    We rely on the community to improve Encore, and we're overwhelmed by your support and encouragement. A huge thank you to @SarojWasti & @ArjunSharda for your contributions to this release!

    What's next

    Over the next couple of weeks, we're going to release a next-generation cloud provisioning system for Encore. Check out this blog post to get a sneak preview. – Remember to vote on your favorite feature on the roadmap!

    As always, if you have questions or feedback, tell us on Slack or our Community Forums.

    We're excited to hear your feedback! ❤️

    Catch you in the cloud, Dom & the Encore team

    Full Changelog: https://github.com/encoredev/encore/compare/v1.8.0...v1.9.0

    Source code(tar.gz)
    Source code(zip)
  • v1.8.0(Oct 13, 2022)

    If there's an error, at least it's a nice one now

    Compiler errors are a source of frustration for most developers, as they often force us to decipher confusing or misleading error messages. To make this a better experience we've taken inspiration from Elm and Rust, and we've modified how Encore reports into human-readable errors.

    Instead of simply reporting a filename, line number, and column number with a single line of text describing the error, Encore now shows a summary of the error, the line(s) of code which caused the error, and also show other lines of code to provide additional context.

    multi-file-error

    All errors returned by Encore will now render in this format. Over the coming months, we plan to improve the readability of all errors by providing additional context or help text within the error itself.

    GoLand Plugin

    Version

    We are happy to announce that Encore now has an official plugin for GoLand and IntelliJ. The plugin allows you to run unit tests on Encore applications from the comfort of your IDE, as well as allowing you to run those same tests in debug mode with breakpoint support!

    image

    As with Encore itself, the plugin is open source. Bug reports and contributions are welcome at encoredev/intellij-plugin.

    Download the plugin today: https://plugins.jetbrains.com/plugin/20010-encore/

    Bugfixes and other improvements

    We're always thankful when we get feedback and bug reports from anyone using Encore. Here are some improvements we've made lately, thanks to your input:

    • We've made multiple improvements to the local dashboard from fixing the font loading to adding scrolling to the logs shown in the trace view.
    • When you use the encore logs command to stream logs, we show a "waiting for logs" message to indicate that the stream is connected successfully.
    • We've fixed an issue with authorization tokens to the Encore platform becoming corrupted and not refreshing correctly.
    • Fixed a bug where if a DI-based API was used in a cronjob, Encore was unable to parse the application if the encore.gen.go file was missing. (Thanks @Willyham for the bug report)
    • Various improvements to the documentation.

    Thanks to our contributors

    We rely on the community to improve Encore, and we're overwhelmed by your support and encouragement. A huge thank you to @kVarunkk, @eddy-geek, @AM1TB, @Minivera, @michizhou for your contributions to this release!

    What's next

    Over the next couple of weeks, we're super excited to announce we'll be releasing Encore native support for per-service configuration, powered by the CUE language. Remember to vote on your favourite feature on the roadmap!

    As always, if you have questions or feedback, tell us on Slack or our Community Forums.

    We're excited to hear your feedback! ❤️

    Catch you in the cloud, Dom & the Encore team

    Full Changelog: https://github.com/encoredev/encore/compare/v1.7.0...v1.8.0

    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(Sep 21, 2022)

    redis caches now available in encore

    In-memory caches are vital when you're building real-time applications like games, ad systems, or financial applications. They're also practical when you want a convenient way to store key values without needing a database. That's why we're excited to let you know that Encore now has native support for in-memory caches, using Redis!

    Here's what you need to know

    • The Encore framework now has a native API for working with caches, and as usual, it works the same across Encore cloud, GCP, and AWS. (Azure coming soon!)
    • Before trying it out, remember to first update using: encore version update and thengo get [email protected]

    Check out the docs to see how the new cache API works.

    Upgrades to Encore Flow

    We've also been busy making improvements to Encore Flow:

    • Cron Jobs are now included in the Encore Flow architecture diagrams, making it dead simple to see which services have Cron Jobs attached.
    • You can now easily download an image of your system architecture using the little camera icon in the upper right corner of the Encore Flow view.

    newflowfeatures

    Local dev dash refresh

    It's been a long time coming, but it's finally done: The local dev dash is now using the same styling as the web platform! We've also made a bunch of usability improvements to make it more intuitive and easier to use. We'd love to hear what you think on Slack! devdash

    Bugfixes and other improvements

    We're always thankful when we get feedback and bug reports from anyone using Encore. Here are some improvements we've made lately, thanks to your input:

    • We've given the Encore website a big performance boost, so it loads faster and feels snappier!
    • We've improved the responsiveness and layout of the docs section so it's easier to use side-by-side with your IDE.
    • We fixed a bug where Flow wouldn't render properly on Firefox.

    Thanks to our contributors

    We rely on the community to improve Encore, and we're overwhelmed by your support and encouragement. Thanks to @BogDAAAMN, @Minivera, @Willyham, @davidmytton, @melkstam, MaxD for your ideas, bug reports and feedback!

    Introducing our new community forums

    For a long time, we've had an active Slack group. It's been a great way for everyone to engage in meaningful conversations, and for us quickly provide help when there are questions. Lately, we've noticed that the drawback with Slack is that it makes it hard for new joiners to discover answers to common questions and refer to past conversations.

    That's why we've launched a community forum!

    We'll use this for asynchronous conversations and to build up a knowledge base of community questions and answers.

    • If you haven't already, sign up and introduce yourself!

    We're not going to stop using Slack, rather we're going to focus it on synchronous and time-sensitive conversations.

    What's next

    In the coming weeks we'll be adding even more flexibility to the Encore framework, with improved support for configuration. We're also working on a big upgrade to infrastructure provisioning, making it more flexible and easier for you to add specific requirements like deploying to existing Kubernetes clusters. - Remember to vote on your favorite feature on the roadmap!

    As always, if you have questions or feedback, tell us on Slack.

    We're excited to hear your feedback! ❤️

    Catch you in the cloud, André & the Encore team

    Source code(tar.gz)
    Source code(zip)
  • v1.6.0(Sep 7, 2022)

    Introducing Encore Flow — Visualize your cloud microservices architecture with one click!

    Flow is the world's first intelligent visual backend architecture tool for the cloud. Flow helps you improve your microservices architecture, and makes it easy for everyone on the team to understand it. It lets you instantly identify which services depend on each other and how they work together. With Flow, building backends has never been easier – from designing your architecture and collaborating on pull requests, to onboarding new team members.

    image

    Flow is now available for all Encore users! If you haven’t tried Encore yet, get started here.

    🥐 If you already have Encore installed, run encore version update to upgrade.

    Flow Key Features

    • Flow gives your entire team an accurate and up-to-date view of your entire system – point and click in all parts of your microservices architecture to instantly reveal how it’s wired.
    • Flow gives you a real-time view of the changes you’re making as you code, and will soon integrate with GitHub to automatically add visual context to every pull request.
    • Use Flow to follow API calls across services and visualize dependencies, to track down bottlenecks before they grow into big problems

    Over the coming months we’ll extend Encore Flow with a suite of intelligent development tools, to make it even simpler to build your cloud backend. Follow us on Twitter or Star Encore on GitHub to stay up to date.

    Azure Pub/Sub

    Encore Pub/Sub now officially supports Azure, bringing the support to all the major cloud providers! Give it a spin and let us know what you think.

    Bug fixes and other improvements

    • Encore now runs Go 1.19.1
    • Encore now provisions Cloud SQL instances with PostgreSQL 14
    • Fixed provisioning of Pub/Sub topics without subscribers

    Thanks to our contributors

    We rely on the community to improve Encore, and we're overwhelmed by your support and encouragement. Thanks to @bjaanes, @Willyham, @raymondbutcher and others for your feedback and contributions!

    Join the most pioneering developer community

    Developers building with Encore are forward-thinkers working on exciting and innovative products. Join the conversation on Slack to see what's going on, learn from others, and share what you're working on.

    What's next

    Over the coming weeks we'll be adding support for configuration, caching, Kubernetes deployments, and more. Vote on your favorite feature on the roadmap!

    If you like what we're up to, why not star Encore here on GitHub?

    As always, if you have questions or feedback, tell us on Slack or just reply to this email.

    We're excited to hear your feedback! ❤️

    Catch you in the cloud,

    The Encore Team

    Source code(tar.gz)
    Source code(zip)
  • v1.5.0(Aug 12, 2022)

    We're excited to announce Encore now supports three of the most highly requested features: Middleware, Validation support, and Dependency Injection! Each one is large enough to warrant its own release but here's a three-for-one!

    This means you can now:

    • Define service-specific or global middleware to implement cross-cutting concerns spanning several endpoints
    • Automatically validate incoming requests before invoking handlers
    • Simplify testing of Encore APIs and services
    • Hook into the service initialization and graceful shutdown process for custom logic

    🥐 Run encore version update to grab the latest version, or read on for more information.

    Encore Middleware

    Middleware has been one of the most highly requested Encore features, and it's finally here! Unlike typical Go HTTP middleware, Encore's middleware operates on fully unmarshalled types which enables some incredible workflows. Here's how you define a middleware:

    import (
        "encore.dev/middleware"
        "encore.dev/rlog"
    )
    
    //encore:middleware target=all
    func MyMiddleware(req middleware.Request, next middleware.Next) middleware.Response {
        resp := next(req)
        rlog.Info("returning response", "payload", resp.Payload)
        return resp
    }
    

    See the middleware docs for more information!

    Validation support

    Encore now supports request validation out of the box! To use it, simplify define a Validate() error method on your request types. For example:

    //encore:api public
    func MyEndpoint(ctx context.Context, p *Params) error {
        // ...
    }
    
    type Params struct {
        Worry bool
    }
    
    func (p *Params) Validate() error {
        if p.Worry {
            return errors.New("don't worry, be happy")
        }
        return nil
    }
    

    See the validation docs for more information!

    Dependency Injection

    You can now define Encore APIs as methods on a Service Struct, which allows you to use dependency injection for easier testing of your Encore API endpoints. It introduces the new //encore:service directive that you can use to define a struct type as a Service Struct. It looks like this:

    //encore:service
    type Service struct { /* dependencies go here */ }
    
    //encore:api public
    func (s *Service) MyAPI(ctx context.Context) error { /* ... */ }
    

    The new Service Struct approach also comes with several other features, like service initialization and graceful shutdown hooks! Read the docs on Service Structs and Dependency Injection for more information.

    Bug fixes and other improvements

    • Fixed a case where the runtime was not fully initialized for test-only packages using sqldb.Named (#335)
    • Fixed trace viewer tooltip being difficult to hover into (#332)
    • Fixed encore.dev/docs keyboard shortcuts

    Thanks to our contributors

    We rely on the community to improve Encore, and we're overwhelmed by your support and encouragement. Thanks to @Willyham, @melkstam, @bjaanes, @Minivera, @davidmytton, @MaxD and others for your feedback and contributions!

    Join the most pioneering developer community

    Developers building with Encore are forward-thinkers working on exciting and innovative products. Join the conversation on Slack to see what's going on, learn from others, and share what you're working on.

    What's next

    Over the coming weeks we'll be adding support for configuration, Azure Pub/Sub, caching, and more. Vote on your favorite feature on the roadmap!

    If you like what we're up to, why not star Encore here on GitHub?

    As always, if you have questions or feedback, tell us on Slack or just reply to this email.

    We're excited to hear your feedback! ❤️

    Catch you in the cloud,

    The Encore Team

    Source code(tar.gz)
    Source code(zip)
  • v1.4.0(Aug 5, 2022)

    Asynchronous event processing, like PubSub, is a core building block in most modern distributed systems. It lets you build systems that communicate with each other by broadcasting events asynchronously. In the last release, we added added GCP support for Encore PubSub, and this week we're adding full AWS support.

    This means you can now:

    • Effortlessly build event driven backend applications and deploy to both GCP and AWS.
    • Off-load expensive business logic into the background.
    • Process queues of work in a reliable, scalable, and cloud-agnostic way.
    • Easily decouple systems from each other.

    🥐 Run encore version update to grab the latest version, or check out the docs to learn how to build with Encore PubSub.

    Bug fixes and other improvements

    • Encore's been updated with Go 1.19 support.
    • The Encore runtime has seen major changes to improve testability and simplicity of new development. (#313)
    • We've squashed a few visual bugs in the Docs and have improved the Search functionality.
    • The local development dashboard now has search for API endpoints, making it easier to use when working on a large application.
    • And much much more!

    Thanks to our contributors

    We rely on the community to improve Encore, and we're overwhelmed by your support and encouragement. Thanks to David Mytton, Minivera, Vilhelm Melkstam, MaxD, Nick Klauer, and John Stern for your feedback and contributions!

    Join the most pioneering developer community

    Developers building with Encore are forward-thinkers working on exciting and innovative products. Join the conversation on Slack to see what's going on, learn from others, and share what you're working on.

    What's next

    Over the coming weeks we'll be adding even more flexibility to the Encore framework, with things like: extended configuration support and dependency injection. Vote on your favorite feature on the roadmap!

    If you like what we're up to, why not star Encore here on GitHub?

    As always, if you have questions or feedback, tell us on Slack or just reply to this email.

    We're excited to hear your feedback! ❤️

    Catch you in the cloud,

    The Encore Team

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Jul 13, 2022)

    We're excited to share Encore's world-class developer experience now extends to asynchronous event processing with the addition of Encore PubSub!

    Pub/Sub is one of the core building blocks of modern distributed systems. This means you can now easily:

    • Effortlessly build event driven backend applications
    • Off-load expensive business logic into the background and not during request processing
    • Process queues of work in a reliable, scalable, and cloud-agnostic way
    • Decouple systems from each other

    Building such applications typically involves endless repetition and tedious boilerplate. No more.

    Run encore version update to grab the latest version and experience it for yourself!

    — If you're new to Encore, check out the Quick Start Guide to get started building.

    Encore PubSub

    Encore PubSub takes the same approach to building distributed systems as the rest of Encore, and makes building event-driven, asynchronous a breeze. With Encore you define your topics and subscriptions directly in your backend code, like any other object.

    With just a few lines of code we have a serverless backend that scales from zero to hundreds of millions of users, with zero boilerplate and with static type safety. Encore takes care of all the complex, boring parts, so you can focus on building your product:

    • Provisioning and configuring the necessary cloud infrastructure
    • Connecting it all together, generating all the boilerplate code and configuration to use the infrastructure within your backend application
    • Connecting it all together with distributed tracing for effortless observability

    The best part of all? It works the same way for local development as well as the major cloud providers. Encore provisions the cloud native infrastructure component for your specific cloud provider of choice, but the code works the same way.

    To define a topic and begin publishing messages is just a handful lines of code:

    import "encore.dev/pubsub"
    
    type SignupEvent struct {
    	Username string
    	Email    string
    }
    
    var Signups = pubsub.NewTopic[*SignupEvent]("user-signups", pubsub.TopicConfig{
    	DeliveryGuarantee: pubsub.AtLeastOnce,
    })
    
    // To publish a message:
    _, err := Signups.Publish(ctx, &SignupEvent{Username: "jane.doe", Email: "[email protected]"})
    

    To begin receiving messages is equally simple:

    import "encore.dev/pubsub"
    
    var _ = pubsub.NewSubscription(
        user.Signups, "send-welcome-email",
        pubsub.SubscriptionConfig[*user.SignupEvent] {
            Handler: SendWelcomeEmail,
        },
    )
    
    func SendWelcomeEmail(ctx context.Context, event *user.SignupEvent) error {
        // .. send email ...
    }
    

    Testing PubSub

    To complement the new PubSub support Encore now comes with a new et (encore testing) package to simplify testing distributed systems.

    We're starting with support for testing PubSub behavior, but over time we plan to expand on it to support easy testing of various distributed system behaviors. Read the package docs for more information.

    Bug fixes and other improvements

    • Improved handling of max connections for local development (#300)
    • Improved keep-alive of encore db shell database sessions (#263)
    • Improved error messages for several common Encore syntax errors
    • Added support for customizing GOARCH and the docker base image for encore eject docker (#269)
    • Improved CORS handling for local development (#276, #278, #286)
    • Fixed running encore run before encore auth login on new systems (#299)
    • Fixed rendering of encore.dev/rlog log output when using structured logging of booleans (#308)

    Thanks to all our contributors

    We rely on the community to improve Encore, and we're overwhelmed by your support and encouragement. Big thanks to @davidmytton, @bscott, @bjaanes and others for your bug reports and feedback!

    Join the most pioneering developer community

    Developers building with Encore are forward-thinkers working on exciting and innovative products. Join the conversation on Slack to see what's going on, learn from others, and share what you're working on.

    What’s next

    Over the coming weeks we'll be adding much requested flexibility to the Encore framework, with improved support for things like: middleware, configuration and dependency injection. Vote on your favorite feature on the roadmap – If you like what's going on, why not give the project a star?

    As always, if you have questions or ideas, come tell us on Slack. We’re excited to hear your feedback! ❤️

    Catch you in the cloud, André & the Encore team

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(May 27, 2022)

    We're hard at work adding much requested flexibility to the Encore framework. In this week's release, we've added native support for HTTP headers in Encore APIs and authentication handlers. No more having to use only JSON!

    This means you can now easily:

    • Model REST APIs like you're used to
    • Return HTTP headers
    • Use the local development dashboard to see how each field will be encoded

    Run encore version update to grab the latest version and experience it for yourself! – If you're new to Encore, check out the Quick Start Guide to get started building.

    Improved authentication support

    Encore now supports a more flexible way to express authentication handlers, using struct payloads in the same way you're used to for regular endpoints. The struct payloads can include multiple fields that can be sourced from either HTTP Headers or query strings.

    That means you can do things like:

    • Implement more advanced authentication methods that go beyond simple Bearer tokens
    • Accept client_id as a query string and an API key in the Authorization header, at the same time
    • Support HTTP Basic Authentication

    Improved client code generation

    The Encore client code generation has received a major upgrade for both TypeScript and Go clients.

    • Support for HTTP headers
    • Support for structured authentication handlers
    • API errors are now reported as structured errors rather than strings
    • The TypeScript client now properly supports raw endpoints, including specifying the request body, HTTP method, and arbitrary fetch options

    Note: The Go client now validates the provided HTTP method for calling raw endpoints. In the rare case that a raw endpoint was called without a valid Method, the behavior of the new client generator will differ by returning an error. In previous versions it instead defaulted to making a GET request.

    Bug fixes and other improvements

    • Forward slashes encoded as %2F within string path segments no longer causes that path segment to be treated as two separate segments.
    • In the rare case that path segment parameters conflict with reserved keywords or names the generated names are now prefixed with _ to avoid name collisions.
    • Blank or missing auth tokens in generated TypeScript clients will no longer be sent in the Authorization header
    • The encore.Meta function now reports the correct value for the APIBaseURL field for local development (#245)
    • Encore now supports ejecting an application as a standalone docker container. See encore eject docker --help for more information.
    • A more helpful error message is now displayed when an environment cannot be found when generating a client (#118)

    Thanks to all our contributors

    We rely on the community to improve Encore, and we're overwhelmed by your support and encouragement. Big thanks to @ValeriaVG, @Qolzam, Prasanna Balaji, @vilhelmmelkstam, and @MaxDanielsson for your bug reports and feedback!

    Join the most pioneering developer community

    Developers building with Encore are forward-thinkers working on exciting and innovative products. Join the conversation on Slack to see what's going on, learn from others, and share what you're working on.

    What’s next

    Over the coming weeks we'll be adding much requested flexibility to the Encore framework, with improved support for things like: middleware, configuration and dependency injection. Vote on your favorite feature on the roadmap – If you like what's going on, why not give the project a star?

    As always, if you have questions or ideas, come tell us on Slack. We’re excited to hear your feedback! ❤️

    Catch you in the cloud, André & the Encore team

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(May 13, 2022)

    As developers, we often find ourselves in situations where we need to change something in our codebase, but don't want to change it everywhere the code is deployed.

    Using Encore's new App Metadata API, you can now query the runtime to find out what environment the application is running in. Which means you can easily load the appropriate configuration files into memory and get the correct behavior for each environment.

    This makes it a breeze to do things like:

    • Use different cloud services per environment
    • Define environment specific business logic

    Check out the docs to learn more.

    Upgrading

    With this release, we've updated the runtime API with the new metadata API's and types. To upgrade you will need to both:

    • Run encore version update to download v1.1.0 of the Encore compiler.
    • In each of your Encore applications, you will also need to run go get -u encore.dev to upgrade to the latest runtime API.

    Bugfixes and other improvements

    • We've made a ton of improvements to Encore's SQLDB handling! Including upgrading to PostgreSQL 14, and adding support for external DB clusters for CI/CD.
    • The Encore runtime now shuts down with grace.
    • Encore now runs on Go 1.18.2.
    • In case you've missed it, we've launched a new visual identity and have given the website a lot of love!
    • ...and much more.

    — Thanks to @davidmytton, @klemmster, @ValeriaVG, @vilhelmmelkstam, @kwihl, and @MaxDanielsson for your contributions, bug reports, and feedback!

    Join the most pioneering developer community

    Developers building with Encore are forward-thinkers working on exciting and innovative products. Join the conversation on Slack to see what's going on, learn from others, and share what you're working on.

    What's next

    Over the coming weeks we'll be releasing a vastly improved web UI, and focus on adding much requested flexibility to the Encore framework. We'll add improved support for things like: http headers in Encore APIs, middleware, and dependency injection.

    As always, if you have questions or feedback, tell us on Slack or just reply to this email. We're excited to hear your feedback! ❤️

    Catch you in the cloud, The Encore team

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Apr 26, 2022)

    We're incredibly excited to announce Encore v1.0. With this release, Encore is fully prepared to support you in your next creative endeavour.

    It's our belief that Encore will transform developers' lives. Our work will become far more joyful and creative. Rather than it being 80% about configuring tools and services that have been reconfigured thousands of times before, we'll spend our days building new products that have a real impact. And that could have huge benefits for society. Imagine the exciting innovations if the world's 25+ million developers are freed up to be five times more productive!

    We hope that Encore will open things up to a broader range of folk. You won't need to have a deep understanding of the nuances of cloud services to develop world-changing software that is available on a global scale. Now more people who are passionate about real-world issues which they're trying to solve will be empowered to have an incredible impact.

    Highlights of what's been added in this release

    AWS Cloud deployments now generally available

    We're happy to announce that we've added full support for deploying your Encore applications to Amazon Web Services. This is a huge milestone, as Encore now supports deploying seamlessly to all major cloud providers.

    If you wish, you can easily deploy your application to all of them, for those multi-cloud bragging rights. With Encore it's as easy as connecting your cloud account. There's no second step.

    Check out the docs to learn how to connect your Encore app to your AWS account and start deploying in minutes.

    Speedier builds and structured logs

    When you deploy your Encore application, the platform takes care of building your app, provisioning the necessary infrastructure, and orchestrating the deployment. With this release, we've made builds blazing fast and laid the foundation for better and more structured build logs. Behind the scenes we've ripped out GCP Cloud Build and replaced it with our own firecracker based builder. If this tickles your fancy, we're busy writing an in-depth article on this very topic. Watch this space for more details.

    structured build logs

    Improvements & Bugfixes

    • We've upgraded the Encore fork of the Go runtime to 1.18.1 (it's now 0.0.1 better than before)

    Catch you in the cloud, The Encore Team

    Source code(tar.gz)
    Source code(zip)
  • v0.23.0(Apr 1, 2022)

    One of the core beliefs behind Encore is that developers shouldn't need to worry about the intricacies of cloud infrastructure. Instead you should focus on being creative and crafting unique software for your users.

    To achieve this, Encore enables you to deploy your applications to any supported clouds (yes plural), without making code changes. We're super excited to announce we've now added full support for Microsoft Azure to the list!

    Float into the flow with Azure:

    • Create a new environment and deploy your app to Azure in minutes.
    • Keep using all Encore features in exactly the same way as before!
    • Run multiple environments across Azure / GCP / Encore for the same app. (AWS dropping soon!)

    Check out the docs to learn more.

    image

    Bugfixes and other improvements

    • Added support for line based comments on struct fields. – Thanks to Javi Alvarez, Valeria Viana Gusmao, Denis Denis, Vilhelm Melkstam, Max D, Alessandro Resta and Richard Palm for your contributions and bug reports. (WOW, what a long list, and what a great community!)

    What's next

    Over the coming weeks we'll be adding AWS to the mix, dropping a huge UI update, and get on with adding native support for Queues and Object storage.

    – Remember, you can share your comments and ideas on our Public Roadmap.

    As always, if you have questions or feedback, join us on Slack or just reply to this email.

    We're excited to hear your feedback!

    Source code(tar.gz)
    Source code(zip)
  • v0.22.0(Mar 28, 2022)

    We're continuously refining the Encore experience to make it even more frictionless, and give you more control and flexibility. This week we've released a bunch of big improvements to how deployments work for all your Encore applications.

    Highlights of what we shipped the past week:

    • Much improved overview – Builds, infrastructure changes, and deploys in one view.
    • No surprises in your cloud bills – You can now choose whether you want to manually approve any infrastructure changes for each environment.
    • You can now easily re-trigger deploys from the Web Platform.

    deployments improved

    Bugfixes and other improvements

    • We refined the internal alerting and monitoring for the Web Platform to ensure availability.
    • We fixed a subtle bug related to parsing errors in app log messages. – Thanks to Valeria Viana Gusmao, Dinesh Katwal, and Glenn Lewis for their bug reports and contributions!

    Join the most pioneering developer community

    Developers building with Encore are forward thinkers working on interesting and exciting projects. Join the conversation on Slack to see what's going on, and share what you're working on.

    What’s next

    Over the coming weeks we’ll be reactivating AWS and Azure support for all Encore users, releasing a polished version of the Web Platform, adding native support for queues and object storage, and much more. – Remember, you can share your comments and ideas on our Public Roadmap.

    As always, if you have questions or feedback, join us on Slack. We’re excited to hear your feedback! ❤️

    Source code(tar.gz)
    Source code(zip)
  • v0.21.0(Mar 18, 2022)

    To celebrate the release of Go 1.18, we’ve updated Encore with first-class support for generics, API fuzzing, and more! Simply run encore version update to upgrade and get all these goodies.

    Generics are here!

    Encore v0.21 comes with full support for Go 1.18's generics! You can now write generic code with Encore, use generic types in API request and response schemas, and more:

    • The automated API documentation has been taught to understand and render generic types
    • The client code generation has been extended to generate generic types

    Fuzzing

    Encore extends Go 1.18's support for fuzzing to include fuzz testing Encore APIs. Use encore test -fuzz=. to start fuzzing! Fuzzing is a great way to improve the security of your APIs by ensuring they can handle arbitrary inputs.

    ✨ Join the most pioneering developer community

    Developers building with Encore are forward thinkers working on interesting and exciting projects. Join the conversation on Slack to see what's going on, and share what you're working on.

    🗓️ What's next

    We'll shortly be releasing improvements to the Deployment UX, and in the coming weeks give you more knobs in the Distributed Tracing dashboard, add native support for Object Storage, and much more!

    — Remember, you can share your comments and ideas on our Public Roadmap.

    We're excited to hear your feedback! ❤️

    Keep building, André (Founder) & the Encore team

    Source code(tar.gz)
    Source code(zip)
  • v0.20.0(Mar 11, 2022)

    🎁 Bring Your Own Domain Names

    Custom Domains You asked for it, and so it's here! We've just released Custom Domains, which lets you serve your Encore powered backend API's from your own domains. No proxy, no certificates, and no hassle!

    The best part? No need to update your CLI tools, just head to the Web Platform and try it out yourself!

    📚 Check out the docs to learn more.

    🔥 PR Environments just got even better

    One of the lesser known — but very powerful — features of Encore just got even better!

    In case you didn't know: When you've linked your app with GitHub, Encore will automatically provision dedicated Preview Environments for each pull request. (See how in the docs)

    PR environments work just like regular development environments, and lets you test your changes before merging. This week, we made PR environments even better, and added full support for Encore's native Cron Jobs!

    💡 Improvements & Bugfixes

    • We've added support for GitHub login to make things even smoother.
    • We upgraded the platform to Go 1.17.8, and are standing ready for the release of 1.18.

    — Thanks to @MaxDanielsson, @VilhelmMelkstam, and @gmlewis for giving us feedback!

    ✨ Join the most pioneering developer community

    Developers building with Encore are forward thinkers working on interesting and exciting projects. Join the conversation on Slack to see what's going on, and share what you're working on.

    🗓️ What's next

    Over the coming weeks we'll be improving the Deployment UX, give you more knobs in the Distributed Tracing dashboard, add native support for Object Storage, and much more!

    — Remember, you can share your comments and ideas on our Public Roadmap.

    We're excited to hear your feedback! ❤️

    Keep building, André (Founder) & the Encore team

    Source code(tar.gz)
    Source code(zip)
  • v0.19.0(Mar 2, 2022)

    When building backend applications you often need to run periodic and recurring tasks. For example, to send a welcome email to everyone who signed up recently. Encore provides native support for these types of use cases using Cron Jobs. Here's how easy it is:

    import "encore.dev/cron"
    
    // Send a welcome email to everyone who signed up in the last two hours.
    var _ = cron.NewJob("welcome-email", cron.JobConfig{
        Title:    "Send welcome emails",
        Every:    2 * cron.Hour,
        Endpoint: SendWelcomeEmail,
    })
    

    That's it! When this is deployed, the Encore Platform will call the SendWelcomeEmail endpoint (not pictured) every 2 hours. There is no need to maintain any infrastructure; Encore itself takes care of the scheduling, monitoring and execution. Hooray! ✨

    What's more, Encore's web platform has a shiny new Cron Jobs dashboard to help you keep track of all your jobs. Check it out:

    Cron Job dashboard

    This means you can now schedule recurring tasks without worrying about:

    • How yet another configuration language works –– it's just plain Go.
    • Setting up and maintaining servers or third-party services –– it's all handled by Encore.
    • Keeping track of what jobs are running in each environment – just check the dashboard!

    To get started, install the latest Encore release with encore version update and upgrade your application's dependency with go get [email protected].

    Check out the docs 📚 to learn more.

    Bugfixes and other improvements

    • Added support for code coverage with encore test -cover (#144)
    • Improved documentation on using external databases
    • Improved documentation on handling database migration errors
    • Improved documentation on how to use GCP (#102)
    • Fixed encore test mistakenly requiring Docker when the app has no database (#98)

    Thanks to @ValeriaVG and @wisdommatt for the contributions!

    Source code(tar.gz)
    Source code(zip)
  • v0.18.0(Feb 15, 2022)

    Happy 2022! (We're a bit late to the party, we know...) We’ve been heads down improving our platform and are super excited to finally announce these product updates. 🎉

    • If you'd like to give Encore a go for the first time, check out our quick start.
    • If you already have Encore installed, you can update with encore version update.

    We’ve just shipped some huge platform improvements to make your applications faster, and ensure our service is more reliable as you’re developing.

    Encore now offers full support for Google Cloud Run, adding an even easier and cheaper way to deploy to your own cloud account. Perfect for getting your next idea up and running quickly.

    We’ve also integrated with Cloudflare, giving you the full power of their edge network, for even lower latency and higher performance. This works transparently across all the cloud providers we support, including Encore Cloud.

    Infrastructure

    🔑 Auth Keys

    Sometimes it’s practical to use the Encore CLI in an automated fashion, for instance to automatically run tests in a CI/CD pipeline beyond what Encore already provides. That was trickier than it should have been, since the CLI required interactive login. But no longer!

    We now support pre-authenticated keys that grant a machine user access to a single Encore application, perfect for your CI environments and other automated tools. — Read more about auth keys in the docs.

    Auth Keys

    🚪 Password-based & Social Login

    Logging in with one-time codes over email can be annoying because you can’t use your password manager. We hear you! That’s why we’re happy to announce we’ve now rolled out password-based login and social login. — Next time you log in you’ll need to set a password using “Reset password” on the login screen, using the same email address as before.

    🗓️ What’s next

    Over the next fews weeks we’ll be adding lots more powerful features to help you build your next great product faster. Soon we’re adding native support for Cron Jobs, Custom API Domains, Object Storage (S3), Pub/Sub, and more. — Remember, you can share your comments and ideas on our Public Roadmap.

    That’s it for this time! As always, if you have questions or feedback, join us on Slack. We’re excited to hear your feedback.

    Source code(tar.gz)
    Source code(zip)
  • v0.17.2(Sep 20, 2021)

    We're excited to announce Encore v0.17, our most feature-packed and best release yet!

    If you'd like to give Encore a go for the first time, check out our quick start. If you already have Encore installed, you can update with encore version update.

    The simplest way to build a REST API

    We've heard you: the Encore developer experience is great, but building REST APIs was too cumbersome. No more! You can now define REST APIs with incredible speed and productivity, through the power of Encore's static analysis and code generation engine. Just take a look:

    // The List endpoint returns a list of blog articles.
    // It can be called simply as:
    //
    //     GET /blog?limit=30&offset=0
    //
    //encore:api public method=GET path=/blog
    func List(ctx context.Context, p *ListParams) (*ListResponse, error) {
    	// Fetch results...
    }
    
    // ListParams are the query parameters for the List endpoint.
    type ListParams struct {
    	Limit int
    	Offset int
    }
    
    // ListResponse is the response schema for the List endpoint.
    type ListResponse struct {
    	Posts []*Post
    }
    

    If it looks just like regular, plain Go code, you'd be exactly right! Since it's a GET endpoint, Encore automatically parses the ListParams fields and parses them from the query string in the HTTP request.

    This approach lets you think and develop your API in terms of functions and data structures, instead of worrying about low-level HTTP request parsing. The end result is a remarkably simple programming paradigm that dramatically increases productivity.

    We call it the Encore Application Model — a combination of static analysis and code generation — and it's all about understanding what you're trying to do and helps you achieve it faster and easier than ever before. By taking all the boilerplate out of backend development we're left with a much more enjoyable developer experience as well.

    ORM Support and Query Helpers

    Encore's SQL Database support now works seamlessly with the large Go ecosystem of ORMs and query helpers! This means if you want to use tools like:

    ... and so on, you can! In your Encore service, use the new sqldb.Named function to get a database object, and then use its Stdlib method to get a *sql.DB object that you can integrate with any of these packages as you see fit.

    package foo
    
    // db is a *sql.DB that is automatically connected
    // to the database belonging to the "foo" service.
    //
    // Like always with Encore, you don't need to worry
    // about provisioning, database passwords, or having
    // to set up schema migrations. It's all taken care of.
    var db = sqldb.Named("foo").Stdlib()
    

    Testing auth endpoints

    If you're building an application with Encore's built-in authentication support, you're in luck! Testing endpoints that required authentication is now much easier than before, with the introduction of auth.WithContext:

    import "encore.dev/beta/auth"
    
    func TestAuthEndpoint(t *testing.T) {
    	ctx = auth.WithContext(context.Background(), "some-user-id", &AuthData{})
    	err := MyAuthEndpoint(ctx)
    	// ...
    }
    
    //encore:api auth
    func MyAuthEndpoint(ctx context.Context) error {
    	// ....
    }
    

    This functionality is actually not limited to testing, and can be used anywhere, including in your business logic for cases where you need to make an API call on behalf of an authenticated user.

    Bugfixes and other improvements

    We also made lots of smaller improvements and bugfixes:

    • Added --port and --listen options to encore run to change listen port/address (#94)
    • Overhauled code generation for increased performance and maintainability
    • Fixed database request tracking in tests (#89)
    • Fixed a bug where the Dev Dashboard sometimes didn't show the latest result (#53)
    • Fixed return type mismatch between Encore runtime and client library (#55)
    • Fixed using unicode in API Explorer (#97)

    We're looking forward to seeing what you build! Join us in Slack to participate in the growing community of Encore developers, and stay tuned for more updates soon!

    Source code(tar.gz)
    Source code(zip)
  • v0.16.3(Aug 25, 2021)

    Encore now has much improved documentation, and an improved encore run experience!

    Revamped Documentation

    • Reworked documentation site from the ground up
    • Open sourced docs so anybody can contribute to better docs
    • Added documentation search
    • Improved CONTRIBUTING.md instructions

    Encore Docs

    Improved encore run experience

    We added more real-time feedback about what Encore is doing when starting up. This especially helps when starting to use Encore and there's lots of things happening (compiling the Go standard library and all app dependencies, pulling docker images for PostgreSQL, creating the database, etc) that take time. See screenshot below!

    encore run

    Minor improvements and bugfixes

    • Added support for GitHub Codespaces (#54)
    • Encore now recognizes both Authorization: Token foo as well as Authorization: Bearer foo for authentication
    • Added ENCORE_DAEMON_DEV=1 to make it easier to develop the Encore daemon
    • Fixed Windows terminal handling (#56)
    • Fixed building from source on Windows (#57)
    • Fixed json.RawMessage handling in generated TypeScript client (#73)
    • Fixed API Explorer sometimes inferring the wrong HTTP method (#74)
    • Fixed incorrectly passing in HTTP body for GET requests (#45)
    • Fixed API Explorer default payload for float64 (#43)
    • Fixed CORS headers for less common HTTP methods
    • Fixed int and uint handling in the API Explorer

    Contributions and thanks

    • @vilhelmmelkstam for his numerous bug reports and bug fixes!
    • @frzam for fixing several bugs related to Windows and terminal handling!
    • @mvp-joe for lots of great feedback and bug reports over in Encore's Slack community
    • And thanks as always to everybody for helping make Encore great.
    Source code(tar.gz)
    Source code(zip)
  • v0.16.2(Jul 9, 2021)

    Encore now has support for defining RESTful APIs in an easy, powerful way!

    API Paths

    Defining APIs can now include the path=/foo/bar and method=FOO parameters to customize the HTTP path and method the API is exposed at:

    type CreateOrderParams struct { /* ... */ }
    type Order struct { /* ... */ }    
    
    //encore:api public path=/orders method=POST
    func CreateOrder(ctx context.Context, p *CreateOrderParams) (*Order, error) { /* ... */ }
    

    Path parameters

    You can also define custom API path parameters such as path=/orders/:id.

    When you specify a parameter, Encore passes that parameter directly to your function as a separate argument, like so:

    type Order struct { /* ... */ }    
    
    //encore:api public path=/orders/:id method=GET
    func GetOrder(ctx context.Context, id int) (*Order, error) { /* ... */ }
    

    Encore automatically performs validation of the parameter, according to the type used in the function signature. In this case id must be an integer. You can also use string, bool, uint8, and so on. You can even use encore.dev/types/uuid.UUID if you want to receive UUIDs.

    Conflicting paths

    Encore parses all the APIs in your application and ensures they don't conflict. For any given API call there can only ever be zero or one API that matches. If you define paths that conflict, Encore raises a compilation error.

    Making API calls between services

    Like always, Encore makes it easy to do API calls between services, and these parameterized APIs work just as easily as before: just call the function: service.GetOrder(ctx, 5).

    Secrets Management

    Encore's web platform now provides much-improved secrets management support. You can view, update, and roll back secrets to previous versions.

    Contributions

    • Many thanks to @Willyham for initiating the custom API path support and implementing a large part of it!
    Source code(tar.gz)
    Source code(zip)
  • v0.15.0(Jul 9, 2021)

    Encore now supports customizing the HTTP path of API raw endpoints. The next release will include complete support for all types of API endpoints.

    //encore:api public raw path=/hello/:name
    func Greet(w http.ResponseWriter, req *http.Request) {
        name := strings.TrimPrefix(req.URL.Path, "/hello/")
        fmt.Fprintf(w, "Hello, %s!", name)
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v0.14.0(Jul 9, 2021)

    Encore now includes even better Distributed Tracing support out of the box!

    Stack traces

    Stack traces are incredibly useful for debugging, but common wisdom is that they're too slow to collect at scale. Encore's deep integration across the stack enabled us to do this in a highly performant way, by only snapshotting program counters at runtime and mapping it to source code information when the trace is viewed. This enables Encore to collect stack traces in less than 300ns!

    The end result is that Encore now provides complete stack traces for all events, including API calls, database queries, log messages, and so on.

    Automatic HTTP Tracing

    Encore now also includes automatic tracing of outgoing HTTP requests. This also works out of the box, and works for all HTTP calls using Go's standard library net/http package.

    Hope you enjoy the new release!

    Source code(tar.gz)
    Source code(zip)
  • v0.13.1(May 4, 2021)

    Encore now has great built-in support for API errors. Features include:

    • Return errors with specific HTTP status codes
    • Return structured errors, along with structured additional details
    • Support for key-value metadata that is propagated between services

    All of this is made possible using the encore.dev/beta/errs package. Read all about it in the Encore docs!

    Source code(tar.gz)
    Source code(zip)
  • v0.12.0(Apr 17, 2021)

    Encore now adds structured log messages to the automatic tracing, using encore.dev/rlog. Log messages written during traced requests are automatically added to the trace.

    The structure of additional fields is preserved, allowing us to index and filter by structured log context later!

    Source code(tar.gz)
    Source code(zip)
  • v0.11.1(Apr 17, 2021)

    This release fixes a few minor issues discovered following the open-source release:

    • Fix encore db shell for local development
    • Add log message when a request to an auth endpoint lacks an Authorization header
    • Improved help for encore gen client
    • Other miscellaneous fixes
    Source code(tar.gz)
    Source code(zip)
Testing ground for CRUD backend using Golang, gRPC, protobufs

blog-example-service Simple example CRUD backend using Golang, gRPC, and protobufs. Using with MongoDB as the database (default) You will need a Mongo

Jordan Weiner 0 Dec 16, 2021
Backend services for the Shiny Sorter image tagging service.

Backend Database The backend database will be MongoDB. Each image will be one object, with the file name, hash, tags, and other metadata. Database Pop

null 0 Aug 4, 2022
Services-inoeg - The Kiebitz Backend Services. Still a work-in-progess, use with care!

Kiebitz Services This repository contains Kiebitz's backend services: A storage service that stores encrypted user & operator settings and temporary d

Kiebitz! 0 Jan 19, 2022
Go-gif - Backend microservice supporting GoGifUrself

go-gif Description Backend microservice supporting GoGifUrself. Dev Process Pull

Michael Bazik 1 Jan 9, 2022
Targetrwe api test - This project provides the backend service for the targetrwe test application

Targetrwe-api This project provides the backend service for the targetrwe test a

null 0 Feb 15, 2022
Go Micro is a framework for distributed systems development

Go Micro Go Micro is a framework for distributed systems development. Overview Go Micro provides the core requirements for distributed systems develop

Asim Aslam 19.9k Jan 3, 2023
Micro-service framework in Go

Kite Micro-Service Framework Kite is a framework for developing micro-services in Go. Kite is both the name of the framework and the micro-service tha

Koding, Inc. 3.2k Jan 9, 2023
Sample full stack micro services application built using the go-Micro framework.

goTemp goTemp is a full stack Golang microservices sample application built using go-micro. The application is built as a series of services that prov

null 66 Dec 26, 2022
NewSQL distributed storage database based on micro service framework

QLite 是基于微服务的 NewSQL 型数据库系统,与传统的一体化数据库不同,该系统将本该内置的多种数据结构(STL)拆分成多个服务模块,每个模块都是独立的一个节点,每个节点都与其主网关进行连接,从而形成分布式存储结构。

null 36 Jun 19, 2022
Kratos is a microservice-oriented governance framework implements by golang

Kratos is a microservice-oriented governance framework implements by golang, which offers convenient capabilities to help you quickly build a bulletproof application from scratch.

Kratos 19.6k Dec 27, 2022
RPC explained by writing simple RPC framework in 300 lines of pure Golang.

Simple GoRPC Learning RPC basic building blocks by building a simple RPC framework in Golang from scratch. RPC In Simple Term Service A wants to call

Ankur Anand 546 Dec 17, 2022
Modern microservice web framework of golang

gogo gogo is an open source, high performance RESTful api framework for the Golang programming language. It also support RPC api, which is similar to

null 40 May 23, 2022
a microservice framework for rapid development of micro services in Go with rich eco-system

中文版README Go-Chassis is a microservice framework for rapid development of microservices in Go. it focus on helping developer to deliver cloud native a

null 2.6k Dec 27, 2022
🦄🌈 YoyoGo is a simple, light and fast , dependency injection based micro-service framework written in Go.

???? YoyoGo is a simple, light and fast , dependency injection based micro-service framework written in Go. Support Nacos ,Consoul ,Etcd ,Eureka ,kubernetes.

YoyoFx 558 Jan 4, 2023
Kratos is a microservice-oriented governance framework implements by golang,

Kratos is a microservice-oriented governance framework implements by golang, which offers convenient capabilities to help you quickly build a bulletproof application from scratch.

Kratos 19.6k Dec 31, 2022
Fastglue is an opinionated, bare bones wrapper that glues together fasthttp and fasthttprouter to act as a micro HTTP framework.

fastglue Overview fastglue is an opinionated, bare bones wrapper that glues together fasthttp and fasthttprouter to act as a micro HTTP framework. It

Zerodha Technology 71 Jun 14, 2022
Another excellent micro service framework

xservice [WIP] Another excellent micro service framework Features RESTful API (base on echo/v4) gRPC & gRPC gateway service & Swagger document generat

新片场 9 May 28, 2022
Kitex byte-dance internal Golang microservice RPC framework with high performance and strong scalability, customized extensions for byte internal.

Kitex 字节跳动内部的 Golang 微服务 RPC 框架,具有高性能、强可扩展的特点,针对字节内部做了定制扩展。

CloudWeGo 5.4k Jan 9, 2023
Solution & Framework for JSON-RPC over HTTP

JROH Solution & Framework for JSON-RPC over HTTP Why not OpenAPI? OpenAPI addresses the definition of RESTful APIs, when it comes to JSON-RPCs, some i

Go Toolkit 11 Mar 13, 2022