Building a REST API in Go with Ent and net/http

Introduction: In this blog post, we’ll walk through creating a simple REST API endpoint using Go’s net/http package and the Ent framework. The example will show how to create a new contact in the database.

Step 1: Setting Up Ent

First, install Ent in your project if you haven’t already:

go get entgo.io/ent/cmd/ent

Next, generate your schema. For this example, we’ll define a Contact schema:

package schema

import (
    "entgo.io/ent"
    "entgo.io/ent/schema/field"
)

type Contact struct {
    ent.Schema
}

func (Contact) Fields() []ent.Field {
    return []ent.Field{
        field.String("name").NotEmpty(),
        field.String("email").NotEmpty().Unique(),
    }
}

After defining the schema, run the code generation:

go generate ./ent

This command generates Go code for your schema, allowing you to interact with your Contact entity through a strongly typed API.

Step 2: Setting Up the HTTP Server

Now, let’s create a simple HTTP server with an endpoint to create a new contact.

package main

import (
    "context"
    "encoding/json"
    "log"
    "net/http"

    "entgo.io/ent/dialect/sql/schema"
    "myapp/ent"
    _ "github.com/mattn/go-sqlite3"
)

type CreateContactRequest struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

func main() {
    // Create an Ent client.
    client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
    if err != nil {
        log.Fatalf("failed opening connection to sqlite: %v", err)
    }
    defer client.Close()

    // Run the migration to create the schema in the database.
    if err := client.Schema.Create(context.Background(), schema.WithAtlas(true)); err != nil {
        log.Fatalf("failed creating schema resources: %v", err)
    }

    http.HandleFunc("/contacts", func(w http.ResponseWriter, r *http.Request) {
        if r.Method != http.MethodPost {
            http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
            return
        }

        var req CreateContactRequest
        if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
            http.Error(w, err.Error(), http.StatusBadRequest)
            return
        }

        contact, err := client.Contact.Create().
            SetName(req.Name).
            SetEmail(req.Email).
            Save(context.Background())
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        json.NewEncoder(w).Encode(contact)
    })

    log.Println("Server is running on http://localhost:8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Step 3: Running the Server

Run the server using:

go run main.go

You can now create a new contact using a POST request:

curl -X POST -H "Content-Type: application/json" -d '{"name":"John Doe","email":"[email protected]"}' http://localhost:8080/contacts

If successful, the server will return the newly created contact, including its ID and other details.

Conclusion

This example demonstrates how to set up a simple REST API endpoint using the Go net/http package in combination with the Ent framework. Ent makes it easy to work with databases in a type-safe manner, and Go’s standard library provides all the tools needed to build robust APIs.

For more advanced use cases, you can explore features like relationships between entities, more complex queries, and integrating with other tools in the Ent ecosystem.


There is no ads to display, Please add some