ข้ามไปยังเนื้อหา

Routing และ Handler

ใน Express handler รับ (req, res, next) ส่วนใน Echo ทุก handler ใช้ signature มาตรฐานเดียวกัน:

func(c echo.Context) error

echo.Context รวม request, response writer, path parameter, query parameter และ helper method ไว้ด้วยกัน คืน nil เมื่อสำเร็จ หรือคืน error เพื่อให้ Echo จัดการ response กรณีล้มเหลว

TypeScript
// Express handler
app.get('/books/:id', (req, res, next) => {
const id = req.params.id;
const book = findBook(id);
if (!book) return res.status(404).json({ message: 'not found' });
res.json(book);
});
Go
// Echo handler
func getBook(c echo.Context) error {
id := c.Param("id")
book, err := findBook(id)
if err != nil {
return echo.NewHTTPError(http.StatusNotFound, "not found")
}
return c.JSON(http.StatusOK, book)
}

Routing API ของ Echo คล้าย Express มาก ชื่อ method แมปตรงกับ HTTP verb

TypeScript
// Express
app.get('/books', listBooks);
app.post('/books', createBook);
app.get('/books/:id', getBook);
app.put('/books/:id', updateBook);
app.delete('/books/:id', deleteBook);
Go
// Echo
e.GET("/books", listBooks)
e.POST("/books", createBook)
e.GET("/books/:id", getBook)
e.PUT("/books/:id", updateBook)
e.DELETE("/books/:id", deleteBook)

c.Param("name") คืนค่า string ของ segment ที่ตั้งชื่อไว้ ใช้ colon :name เหมือนกับ Express

TypeScript
// Express
app.get('/users/:id/posts/:postId', (req, res) => {
const { id, postId } = req.params;
res.json({ userId: id, postId });
});
Go
// Echo
e.GET("/users/:id/posts/:postId", func(c echo.Context) error {
userID := c.Param("id")
postID := c.Param("postId")
return c.JSON(http.StatusOK, map[string]string{
"userId": userID,
"postId": postID,
})
})

c.QueryParam("name") อ่านค่า query ตัวเดียว ส่วน c.QueryParams() คืนทั้งหมดเป็น url.Values (คือ map[string][]string)

TypeScript
// Express
app.get('/books', (req, res) => {
const { page = '1', limit = '10' } = req.query;
res.json({ page, limit });
});
Go
// Echo
e.GET("/books", func(c echo.Context) error {
page := c.QueryParam("page")
limit := c.QueryParam("limit")
if page == "" { page = "1" }
if limit == "" { limit = "10" }
return c.JSON(http.StatusOK, map[string]string{
"page": page, "limit": limit,
})
})

NestJS controller เป็น class ส่วนใน Go รูปแบบ idiomatic คือ struct ที่มี method เป็นตัว handler แล้วทำ dependency injection ผ่าน field ของ struct

TypeScript
// NestJS controller
@Controller('books')
export class BooksController {
constructor(private readonly booksService: BooksService) {}
@Get(':id')
findOne(@Param('id') id: string) {
return this.booksService.findOne(id);
}
}
Go
// Echo — handler struct (manual DI)
type BookHandler struct {
store BookStore
}
func NewBookHandler(s BookStore) *BookHandler {
return &BookHandler{store: s}
}
func (h *BookHandler) Get(c echo.Context) error {
id := c.Param("id")
book, err := h.store.FindByID(c.Request().Context(), id)
if err != nil {
return echo.NewHTTPError(http.StatusNotFound, err.Error())
}
return c.JSON(http.StatusOK, book)
}
// ลงทะเบียนใน main.go:
// bh := NewBookHandler(store)
// e.GET("/books/:id", bh.Get)

รันบนเครื่องของคุณ — ต้องการ Echo module และ network port

Echo handler คืนค่าชนิดใด?
อ่าน path parameter ชื่อ "id" ใน Echo อย่างไร?
อ่าน query string ชื่อ "page" ใน Echo อย่างไร?
รูปแบบ idiomatic ของ Go ที่เทียบเท่า NestJS controller class คืออะไร?