# README
Leaf
A modern backend project that utilizes a range of tools and libraries for type-safe database queries, GraphQL API, migration management, and more.
Key Technologies
- gqlgen: GraphQL-first type-safe server.
- Goose: Database migrations management.
- Go Fiber: High-performance web framework using fastHTTP.
- Go Mail: Mail service integration, supports multiple receipients with attachments
- JWT v5: Application authentication + custom OAuth token validation
- pgx v5: PostgreSQL driver with connection pooling.
- sqlc: Type-safe database query generation.
- dotenv: Manages environment variables.
- Validator v10: Input validation with custom messages.
- zerolog: Efficient logging for events and errors.
Project Setup
Follow the steps below to set up your development environment and get started with the Leaf project.
1. Set up PostgreSQL Database
- Install PostgreSQL (version 17 recommended). You can download it from the official PostgreSQL website (https://www.postgresql.org/download/).
- Create a new database by running the following commands in your PostgreSQL CLI or a database management tool:
CREATE DATABASE db_leaf;
- Configure your environment variables: Add the PostgreSQL connection string (DSN) to your
.env
file:
DATABASE_URL=postgres://postgres:password@localhost:5432/db_leaf?sslmode=disable
- Start PostgreSQL: You can start the PostgreSQL service manually by running:
pg_ctl -D "/path/to/your/pg_data" start
- Create a migration: To create a new migration, such as a
users
table, run:
goose -dir ./db/migrations create create_users_table sql
- Apply migrations: Run the following command to apply migrations to your PostgreSQL database:
goose -dir ./db/migrations postgres "postgres://postgres:password@localhost:5432/db_leaf?sslmode=disable" up
- Rollback a migration: If you want to undo the last migration, use:
goose -dir ./db/migrations postgres "postgres://postgres:password@localhost:5432/db_leaf?sslmode=disable" down
- Reset all migrations: To reset and rollback all migrations, run:
goose -dir ./db/migrations postgres "postgres://postgres:password@localhost:5432/db_leaf?sslmode=disable" reset
- Start the application: Once migrations are applied, run the application:
2. Install SQLC
SQLC is used to generate type-safe database queries. Follow these steps to set it up:
-
Install SQLC: Download and install SQLC to generate database queries:
-
Configure SQLC: The
sqlc.yml
file contains configuration for your database schema and queries. -
Define the database schema: Place your SQL schema files in the
db/schema
directory. -
Define your queries: Write SQL queries in the
db/queries
directory. -
Generate models and queries: Run the following command to generate type-safe database code:
sqlc generate
The generated models, queries, and queriers will be placed in the db/generated
directory.
3. Set up GraphQL with gqlgen
gqlgen
is used to generate a type-safe GraphQL API. It provides tools for automatic generation of resolvers, types, and models.
-
Install gqlgen: The project already has
gqlgen
installed. It is used to generate GraphQL queries, mutations, models, resolvers, inputs, and more. -
Configure gqlgen: The
gqlgen.yml
file contains configuration for the GraphQL models and resolvers. -
Generate GraphQL code: To generate the types, resolvers, and models, run:
go run github.com/99designs/gqlgen generate
-
GraphQL Schemas: All GraphQL schemas are located in the
graph/schema/*.graphqls
directory. Example:user.graphqls
. The cursor pagination is added to the existing models along with sort and filter types for each models. -
Generated Models: The models will be generated in
graph/model/models_gen.go
. You can separate them into individual files for better organization (e.g.,user.go
for user-related models). -
Generated Resolvers: The resolvers are created in
graph/resolvers/{name}.resolvers.go
. Example:user.resolvers.go
.
File Uploads
The project uses gqlgen Upload Scalar type for graphql. Example of Single File upload
curl --location 'http://127.0.0.1:3000/graphql' \
--header 'Authorization: Bearer Token' \
--form 'operations="{
\"query\": \"mutation SingleUpload(\$file: Upload\!, \$folderId: Int\!) { singleUpload(file: \$file, folderId: \$folderId) { id name slug filePath fileType fileBytes fileContentType autoDownload folderId createdAt updatedAt createdBy updatedBy } }\",
\"variables\": { \"file\": null, \"folderId\": 3 }
}"' \
--form 'map="{ \"0\": [\"variables.file\"] }"' \
--form '0=@"/D:/samplefile.txt"'
Example of Multiple File upload
curl --location 'http://127.0.0.1:3000/graphql' \
--header 'Authorization: Bearer Token' \
--form 'operations="{
\"query\": \"mutation (\$files: [Upload\!]\!, \$folderId: Int\!) { multipleUpload(files: \$files, folderId: \$folderId) { id name slug filePath fileType fileBytes fileContentType autoDownload folderId createdAt updatedAt createdBy updatedBy } }\",
\"variables\": { \"files\": [null,null], \"folderId\": 3 }
}"' \
--form 'map=" { \"0\": [\"variables.files.0\"], \"1\": [\"variables.files.1\"] }"' \
--form '0=@"/D:/samplefile1.txt"' \
--form '1=@"/D:/samplefile2.txt"'
Additional Notes
- Environment Variables: You can use a
.env
file to store and manage your environment variables securely. - Custom Validation: Use
validator.v10
for custom validation of user input in GraphQL mutations and queries. - Logging: The
zerolog
library is used for efficient logging of events and errors throughout the application.