golang-gin-realworld-example-app
Exemplary real world application built with Golang + Gin
Top Related Projects
"The mother of all demo apps" — Exemplary fullstack Medium.com clone powered by React, Angular, Node, Django, and many more
Exemplary real world application built with React + Redux
ASP.NET Core backend implementation for RealWorld
Example Spring codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld API spec.
Exemplary real world backend API built with Laravel
Quick Overview
The gothinkster/golang-gin-realworld-example-app is a Go implementation of the "RealWorld" backend API spec using the Gin web framework. It serves as a reference for building scalable and maintainable RESTful APIs in Go, following best practices and demonstrating how to structure a Golang web application.
Pros
- Implements a real-world application, providing practical examples of Go and Gin usage
- Well-structured codebase with clear separation of concerns
- Includes authentication, database integration, and API endpoint implementations
- Follows the RealWorld spec, making it easy to compare with other language/framework implementations
Cons
- May not cover all edge cases or advanced features of a production-ready application
- Documentation could be more extensive for newcomers to Go or Gin
- Some parts of the codebase might benefit from additional comments or explanations
- Limited test coverage in some areas
Code Examples
- Defining a route in Gin:
func (r *articleRouter) Routes() {
r.router.GET("/", r.articleList)
r.router.GET("/:slug", r.articleRetrieve)
r.router.POST("/", middleware.AuthMiddleware(r.authService), r.articleCreate)
r.router.PUT("/:slug", middleware.AuthMiddleware(r.authService), r.articleUpdate)
r.router.DELETE("/:slug", middleware.AuthMiddleware(r.authService), r.articleDelete)
}
- Handling a request in a controller:
func (r *articleRouter) articleCreate(c *gin.Context) {
var json articleCreateRequest
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
userID := c.MustGet("my_user_id").(uint)
if article, err := r.articleService.CreateArticle(json.Article, userID); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err})
} else {
c.JSON(http.StatusCreated, gin.H{"article": article})
}
}
- Database interaction using GORM:
func (as *ArticleService) CreateArticle(article Article, userID uint) (Article, error) {
tx := as.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := tx.Error; err != nil {
return article, err
}
if err := tx.Create(&article).Error; err != nil {
tx.Rollback()
return article, err
}
return article, tx.Commit().Error
}
Getting Started
To run the application:
-
Clone the repository:
git clone https://github.com/gothinkster/golang-gin-realworld-example-app.git
-
Install dependencies:
go mod download
-
Set up the database (MySQL) and update the connection string in
config/config.go
-
Run the application:
go run main.go
The API will be available at http://localhost:8080
.
Competitor Comparisons
"The mother of all demo apps" — Exemplary fullstack Medium.com clone powered by React, Angular, Node, Django, and many more
Pros of realworld
- Comprehensive project with multiple frontend and backend implementations
- Serves as a central hub for various RealWorld examples
- Provides a standardized spec for consistent implementation across platforms
Cons of realworld
- May be overwhelming for beginners due to its extensive nature
- Requires more time to navigate and understand the full project structure
- Less focused on a single technology stack compared to specific implementations
Code Comparison
golang-gin-realworld-example-app:
func (u *UserModel) Create() error {
return db.Create(u).Error
}
realworld (JavaScript example):
export function createUser(user) {
return axios.post('/api/users', { user });
}
The golang-gin-realworld-example-app provides a more specific implementation using Go and Gin, while realworld offers a generic example that can be adapted to various languages and frameworks.
Summary
realworld serves as a comprehensive reference for building real-world applications across multiple platforms, while golang-gin-realworld-example-app focuses on a specific Go implementation using the Gin framework. The choice between them depends on whether you need a broad overview of different implementations or a targeted Go-based solution.
Pros of node-express-realworld-example-app
- More extensive documentation and setup instructions
- Larger community and ecosystem around Node.js and Express
- Better support for asynchronous operations with async/await syntax
Cons of node-express-realworld-example-app
- Potentially slower performance compared to Go's compiled code
- Less type safety and compile-time checks than Go
- Higher memory usage due to Node.js runtime
Code Comparison
node-express-realworld-example-app:
router.post('/users', async (req, res, next) => {
try {
const user = await User.create(req.body.user);
return res.json({user: user.toAuthJSON()});
} catch(error) {
return next(error);
}
});
golang-gin-realworld-example-app:
func Register(c *gin.Context) {
var user model.User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return
}
if err := user.Register(); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
c.JSON(http.StatusCreated, gin.H{"user": user.Serialize()})
}
The Node.js example uses async/await for handling asynchronous operations, while the Go example uses Gin's context and error handling. The Go code is more verbose but provides stronger type checking and error handling.
Exemplary real world application built with React + Redux
Pros of react-redux-realworld-example-app
- More comprehensive frontend implementation with React and Redux
- Larger community and ecosystem for React-based applications
- Better suited for complex, interactive user interfaces
Cons of react-redux-realworld-example-app
- Steeper learning curve for developers new to React and Redux
- Potentially slower initial load times compared to server-side rendered applications
- More client-side processing, which may impact performance on low-end devices
Code Comparison
react-redux-realworld-example-app (JavaScript):
const mapStateToProps = state => ({
...state.article,
currentUser: state.common.currentUser
});
const mapDispatchToProps = dispatch => ({
onLoad: payload => dispatch({ type: ARTICLE_PAGE_LOADED, payload }),
onUnload: () => dispatch({ type: ARTICLE_PAGE_UNLOADED })
});
golang-gin-realworld-example-app (Go):
func ArticleCreate(c *gin.Context) {
articleModelValidator := NewArticleModelValidator()
if err := articleModelValidator.Bind(c); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return
}
// ... (additional logic)
}
The React-Redux example showcases state management and component lifecycle, while the Go-Gin example demonstrates server-side routing and request handling. Each approach has its strengths depending on the project requirements and team expertise.
ASP.NET Core backend implementation for RealWorld
Pros of aspnetcore-realworld-example-app
- More comprehensive documentation and setup instructions
- Larger community and ecosystem around ASP.NET Core
- Better integration with Microsoft technologies and Azure cloud services
Cons of aspnetcore-realworld-example-app
- Potentially higher resource usage compared to the Go implementation
- Steeper learning curve for developers new to C# and .NET ecosystem
- Less flexibility in terms of deployment options compared to Go
Code Comparison
aspnetcore-realworld-example-app (C#):
public async Task<IActionResult> GetArticle(string slug)
{
var article = await _context.Articles
.Include(x => x.Author)
.Include(x => x.ArticleTags)
.ThenInclude(x => x.Tag)
.FirstOrDefaultAsync(x => x.Slug == slug);
if (article == null)
return NotFound();
return Ok(new { article = await article.ToArticleResponse(_currentUserAccessor.GetCurrentUsername(), _mapper) });
}
golang-gin-realworld-example-app (Go):
func ArticleRetrieve(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := article.FindOneArticle(&article.ArticleModel{Slug: slug})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
return
}
serializer := ArticleSerializer{c, articleModel}
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
}
The C# code demonstrates more advanced ORM features and includes eager loading, while the Go code is more straightforward but may require additional queries for related data.
Example Spring codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld API spec.
Pros of spring-boot-realworld-example-app
- More comprehensive test coverage, including integration tests
- Better documentation and code comments
- Utilizes Spring Boot's robust ecosystem and dependency injection
Cons of spring-boot-realworld-example-app
- Larger codebase and potentially higher resource usage
- Steeper learning curve for developers new to Spring Boot
- Slower startup time compared to the Go implementation
Code Comparison
spring-boot-realworld-example-app:
@GetMapping("/articles/{slug}")
public ResponseEntity<SingleArticleResponse> getArticle(@PathVariable("slug") String slug) {
return articleQueryService.findBySlug(slug)
.map(article -> ResponseEntity.ok(new SingleArticleResponse(article)))
.orElseThrow(ResourceNotFoundException::new);
}
golang-gin-realworld-example-app:
func ArticleGet(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := article.FindOneArticle(&article.ArticleModel{Slug: slug})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
return
}
serializer := ArticleSerializer{c, articleModel}
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
}
The Spring Boot example uses annotations and optional types, while the Go example uses explicit error handling and a more procedural approach. The Spring Boot code is more concise but may be less immediately clear to those unfamiliar with the framework.
Exemplary real world backend API built with Laravel
Pros of laravel-realworld-example-app
- Built with Laravel, a popular PHP framework with extensive documentation and community support
- Includes built-in authentication and authorization features
- Offers a more structured and opinionated approach to application development
Cons of laravel-realworld-example-app
- May have slower performance compared to the Go-based implementation
- Requires more server resources due to PHP's nature
- Less suitable for high-concurrency scenarios
Code Comparison
laravel-realworld-example-app (PHP):
public function login(LoginRequest $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
return $this->respondWithToken(Auth::user()->getRememberToken());
}
return $this->respondError('Invalid credentials', 401);
}
golang-gin-realworld-example-app (Go):
func Login(c *gin.Context) {
var loginValidator LoginValidator
if err := c.ShouldBindJSON(&loginValidator); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
user, err := FindOneUser(&User{Email: loginValidator.User.Email})
if err != nil {
c.JSON(http.StatusForbidden, gin.H{"error": "Invalid email or password"})
return
}
if user.checkPassword(loginValidator.User.Password) != nil {
c.JSON(http.StatusForbidden, gin.H{"error": "Invalid email or password"})
return
}
serializer := UserSerializer{c, user}
c.JSON(http.StatusOK, gin.H{"user": serializer.Response()})
}
The Laravel example showcases a more concise login implementation, while the Go version offers more explicit error handling and type safety.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Golang/Gin codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld spec and API.
This codebase was created to demonstrate a fully fledged fullstack application built with Golang/Gin including CRUD operations, authentication, routing, pagination, and more.
Directory structure
.
âââ gorm.db
âââ hello.go
âââ common
â âââ utils.go //small tools function
â âââ database.go //DB connect manager
âââ users
| âââ models.go //data models define & DB operation
| âââ serializers.go //response computing & format
| âââ routers.go //business logic & router binding
| âââ middlewares.go //put the before & after logic of handle request
| âââ validators.go //form/json checker
âââ ...
...
Getting started
Install Golang
Make sure you have Go 1.13 or higher installed.
https://golang.org/doc/install
Environment Config
Set-up the standard Go environment variables according to latest guidance (see https://golang.org/doc/install#install).
Install Dependencies
From the project root, run:
go build ./...
go test ./...
go mod tidy
Testing
From the project root, run:
go test ./...
or
go test ./... -cover
or
go test -v ./... -cover
depending on whether you want to see test coverage and how verbose the output you want.
Todo
- More elegance config
- Test coverage (common & users 100%, article 0%)
- ProtoBuf support
- Code structure optimize (I think some place can use interface)
- Continuous integration (done)
Top Related Projects
"The mother of all demo apps" — Exemplary fullstack Medium.com clone powered by React, Angular, Node, Django, and many more
Exemplary real world application built with React + Redux
ASP.NET Core backend implementation for RealWorld
Example Spring codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld API spec.
Exemplary real world backend API built with Laravel
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot