Go 언어와 MongoDB로 스키마없는 데이터를 관리하는 API를 만들어 보았다.

소개



안녕하세요

필요에 육박하여 문서형 DB의 하나인 MongoDB를 만져야 할 기회가 있었으므로 그 공유(지금 무렵?w)

Go 언어를 예로 MongoDB로 간단한 API를 만들고 싶습니다.

MongoDB와의 연결



드라이버 도입



MongoDB는 자체 프로토콜을 사용하므로 드라이버를 사용해야 합니다.

※이번은 스타수로부터 이쪽의 드라이버를 사용하게 하기로 했습니다.
htps : // 기주 b. 코 m / 몽고 db / 몬고 - d ゔ ぇ r

※도입 방법의 거친 설명은 전회의 기사로 정리하고 있습니다.
htps : // 이 m / p 19 / ms / t cd d2b452477b1 a d7 ae d

Go 언어에서 연결



필요한 패키지는 이쪽

db/main.go
import (
    "context"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

실코드는 이 2행으로 완결합니다.

db/main.go
    clientOptions := options.Client().ApplyURI("mongodb://db")
    client, _ := mongo.Connect(context.TODO(), clientOptions)

ApplyURI()의 인수에 있는 「db」가 host가 됩니다만, 이번은 docker-compose를 이용하고 있기 때문에 「db」라고 하는 이름으로 액세스 할 수 있습니다.
  • docker-compose.yml
  • htps : // 기주 b. 코 m/〇 오징어 19/고-몽고-mp ぇ-아피/bぉb/마s r/도 c케 r-코 m 포세. yml


  • 멋지게 함수화하면

    db/main.go
    func ConnectMongoDB() *mongo.Client {
        clientOptions := options.Client().ApplyURI("mongodb://db")
        client, err := mongo.Connect(context.TODO(), clientOptions)
        if err != nil {
            log.Fatal(err)
        }
        return client
    }
    

    이런 느낌입니까?

    컬렉션 만들기



    그런 다음 컬렉션을 만들어야 합니다.
    ※ 컬렉션은 문서의 집합 단위입니다.

    컬렉션을 만들려면 mongo.Client의 Collection 메서드를 사용할 수 있습니다.
    반환 값으로 mongo.Collection 핸들러가 반환됩니다.
    ※향후는 주로 이 핸들러를 사용해 컬렉션을 조작해 가게 됩니다.

    db/main.go
        collection := client.Database("test").Collection("users")
    

    이번에는 "users"라는 컬렉션을 만들고 있습니다.

    새 문서 만들기



    POST의 끝점을 통해 users 컬렉션에 새 문서를 등록해 봅니다.
    JSON을 POST할 수 있도록 합니다.

    이하 라우팅 및 핸들러

    main.go
        e.POST("/user", func(c echo.Context) error {
            jsonBody := echo.Map{}
            if err := c.Bind(&jsonBody); err != nil {
                errorResponse := ErrorResponse{Message: "Bad Request"}
                return c.JSON(http.StatusBadRequest, errorResponse)
            }
            result, _ := collection.InsertOne(context.TODO(), jsonBody)
            response := Response{ID: result.InsertedID}
            return c.JSON(http.StatusOK, response)
        })
    

    요청의 Body 매개 변수를 c.Bind()로 Go 언어의 map에 매핑하고 있습니다.
    ※ Web framework로 Echo를 사용하고 있습니다. htps: // 에쵸.ぁbs한 ck. 코m/구이데
    새 레코드를 만들려면 InsertOne 메서드를 사용합니다.

    즉시 등록해 보겠습니다.



    응답은 문서의 ID인 ObjectId를 반환합니다.

    문서 참조



    계속해서, 방금 등록한 문서가 제대로 등록되어 있는지 GET 리퀘스트로 확인해 보겠습니다.

    핸들러에서

    main.go
        e.GET("/user/:_id", func(c echo.Context) error {
            raw_id := c.Param("_id")
            _id, _ := primitive.ObjectIDFromHex(raw_id)
            result := echo.Map{}
            if err := collection.FindOne(context.TODO(), bson.M{"_id": _id}).Decode(&result); err != nil {
                errorResponse := ErrorResponse{Message: "Not Found"}
                return c.JSON(http.StatusNotFound, errorResponse)
            }
            return c.JSON(http.StatusOK, result)
        })
    

    포인트는, primitive 패키지의 ObjectIDFromHex 함수를 사용해,
    16진수의 문자열이 생긴 ObjectId를 올바른 ObjectId로 변환하는 처리를 끼우는 곳입니다.
    ※내부적인 것은 잘 모르겠습니다. 죄송합니다.

    ObjectId를 요청 경로에 넣고 GET하면



    방금 POST한 JSON이 제대로 반환되고 있습니다.

    문서 삭제



    마지막으로 삭제입니다.

    특히 눈에 띄는 곳은 없지만 핸들러는

    main.go
        e.DELETE("/user/:_id", func(c echo.Context) error {
            raw_id := c.Param("_id")
            _id, _ := primitive.ObjectIDFromHex(raw_id)
            result, _ := collection.DeleteOne(context.TODO(), bson.M{"_id": _id})
            return c.JSON(http.StatusOK, result)
        })
    

    임시 구현이므로 DeleteOne 메서드의 반환 값을 그대로 응답합니다. .
    요청 경로에 ObjectId를 넣고 DELETE 메서드로 요청하면 문서가 삭제됩니다.



    일단 GET에서도 확인



    제대로 문서가 삭제되었습니다.

    마지막으로



    이번은 매우 담백한 것입니다만, 향후는 mongo의 쿼리에도 자세하게 되고 싶다. 그렇다고 해야 한다.

    읽어 주셔서 감사합니다.

    이번 소스 코드는 여기에서 공개하고 있습니다.
    htps : // 기주 b. 코 m / 〇 오징어 19 / GO-MONGO mp ぇ- API

    참고



  • MongoDB 공식 튜토리얼
  • htps //w w. 몽고 db. 코 m / b ぉ g / 포 st / 몽고 db go d ri


  • 공식 API 문서

  • htps: //아이 c. rg/고. 몽고 db. 오 rg / 몽고 d 리 ゔ r / 몽고

  • 좋은 웹페이지 즐겨찾기