Quick start
Create your project
First of all, you must have the Go compiler installed on your system, I recommend you to use the latest version (1.19.1 at the time or writing this article).
Then you can install the encore CLI, by using brew
(the recommended version), or you can also curl the installation script directly
curl -L https://encore.dev/install.sh | bash
Once you're done, verify that you can run encore
in your terminal!
You can now create the project, simply run encore app create
and select the Hello World
template.
~/DEV/GO/Blog ❯ encore app create ? App Name (lowercase letters, digits, and dashes) demo-blog ? Select app template: Hello World (Encore introduction) Downloaded template hello-world. Successfully created app demo-blog! App ID: demo-blog-n8w2 Web URL: https://app.encore.dev/demo-blog-n8w2 Useful commands: encore run Run your app locally encore test ./... Run tests git push encore Deploys your app Get started now: cd demo-blog && encore run
Sign in ?
You may have noticed that you have to sign in to the encore website in order to complete your project creation, this is a mandatory step that can not be skipped. It is used for you to access the web dashboard, and facilitate the deployment if you want to use the cloud hosting.
Start your app
Navigate to the newly created folder, then simply type encore run
in your terminal.
✔ Building Encore application graph... Done! ✔ Analyzing service topology... Done! ✔ Generating boilerplate code... Done! ✔ Compiling application source code... Done! ✔ Starting Encore application... Done! Encore development server running! Your API is running at: http://localhost:4000 Development Dashboard URL: http://localhost:37193/testencore-fy8i 10:09AM INF registered API endpoint endpoint=World path=/hello/:name service=hello 10:09AM INF listening for incoming HTTP requests
The Hello World endpoint
The Hello World
template come with an Hello World
endpoint, you can make an HTTP request to http://localhost:4000/hello/:name
to get a response saying hello to the name you used at the :name
parameter.
~/DEV/GO/Blog ❯ curl -f http://localhost:4000/hello/Tristan { "Message": "Hello, Tristan!" }
Navigate to the hello/hello.go
file, as you can see, it's mainly plain Go code, with a few things to notice.
If you look at the World
function, you can notice a special comment just above :
//encore:api public path=/hello/:name
func World(ctx context.Context, name string) (*Response, error) {
msg := "Hello, " + name + "!"
return &Response{Message: msg}, nil
}
type Response struct {
Message string
}
The //encore:api public path=/hello/:name
comment tells the Encore compiler that this function is exposed to the public API, with a certain path, which can contain a parameter.
This parameter can be automatically retrieved with function parameters.
The Response
struct only represent the shape of the JSON response which will be returned to the user.
Note that you can make changes to the code, it will be auto-reloaded by Encore!
The development dashboard
Encore come with a nice looking dashboard to help you debug, test, and inspect you app.
To access it, navigate to http://localhost:4000
.
The dashboard provide a tool for quickly testing your API endpoints (same as Swagger), some metrics regarding your last requests, an auto-generated API doc and a tool called Flow
, that can be used to get an overview of all you app.
Authentication
Let's add a simple authentication to our /hello
route. To do so, you must replace the public
access level by auth
in the //encore:api
comment.
//encore:api auth path=/hello/:name
If you save the file now, you will get a Encore compilation error:
Changes detected, recompiling...
hello/hello.go:20:1: cannot use "auth" access type, no auth handler is defined in the app
That's right, we have to define a function that will handle our authentication:
//encore:authhandler
func AuthHandler(ctx context.Context, token string) (auth.UID, error) {
return "", &errs.Error{
Code: errs.Unauthenticated,
Message: "invalid token",
}
}
We tell encore that this function is used as an AuthHandler
with the //encore:authhandler
comment. This function will receive a Context
and a token.
The token come from the Authorization: Bearer <token>
HTTP header.
Let's modify the function to integrate a very basic check:
//encore:authhandler
func AuthHandler(ctx context.Context, token string) (auth.UID, error) {
if token != "secret" {
return "", &errs.Error{
Code: errs.Unauthenticated,
Message: "invalid token",
}
}
return auth.UID("user"), nil
}
If the bearer token is secret
, we authorize the user, simple as that!
Now, if you try to query the endpoint, you will get a 401 Unauthorized
error:
~/DEV/GO/Blog/demo-blog master ❯ curl http://localhost:4000/hello/Tristan { "code": "unauthenticated", "message": "invalid auth param", "details": null }
But if you pass the Authorization
header:
~/DEV/GO/Blog/demo-blog master ❯ curl -H "Authorization: Bearer secret" http://localhost:4000/hello/Tristan { "Message": "Hello, Tristan!" }
And voila, you can of course use an external auth provider like Firebase, Supabase, or your custom JWT logic.