# Golang -- Backend (Sprint1)
contributed by < `ArielWu0203` >
###### tags: `Backend`
[GitHub : pd1-learning](https://github.com/ArielWu0203/pd1-learning)
## Goal
- [x] Set up endpoint service on [localhost](http://localhost) with port 3000
- [x] Set up a hello world page sent back from `http://localhost:3000/`
- [x] Create the `Problems` collection in MongoDB with Robomongo
- [x] Create several documents with the following attributes
- [x] Pid (int)
- [x] Title (String)
- [x] Solution (Boolean)
- [x] Acceptance (Float)
- [x] Complete the function of the endpoint `GET http://localhost/api/problem` that retreives the data from MongoDB with MongoDB-go-driver
## Install the MongoDB Go Driver
```=
$ cd go/src
$ go get go.mongodb.org/mongo-driver
```
## Connect to DB
```go=
// Set client options
// options.Client() : creates a new ClientOptions instance.
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
// Connect to MongoDB
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}
// Check the connection
err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to MongoDB!")
```
* context
* context switch : 當使用權要從 A process 交給 B process 時,A process 的狀態需要被保存下來,記錄在 PCB 中,再載入 B process 。
* context.Background() :
* 已先初始化。
* return non-nil, empty Context.
* No canceled, No value, No deadline.
* 通常用在 main function, top-level Context, parent Context.
* context,TODO() :
* 已先初始化。
* return non-nil, empty Context.
* 不清楚、不確定時才使用。
* More links
* [package context](https://godoc.org/context)
* [上下文 Context](https://draveness.me/golang/concurrency/golang-context.html)
* [examples : Golang Context](https://juejin.im/post/5a6873fef265da3e317e55b6)
* Collection
```go=
collection := client.Database(db_name).Collection(collection_name)
```
* Disconnect
```go=
err = client.Disconnect(context.TODO())
if err != nil {
log.Fatal(err)
}
fmt.Println("Connection to MongoDB closed.")
```
## Insert Documents
```go=
func ExampleInsertDocs(collection *mongo.Collection) {
// Create several documents in DB
Doc1 := Problem{1, "Zuma Game", false, 40.2}
Doc2 := Problem{2, "Word Subsets", true, 46.2}
Doc3 := Problem{3, "Word Search", false, 32.9}
Docs := []interface{}{Doc1, Doc2, Doc3}
insertResult, err := collection.InsertMany(context.TODO(), Docs)
if err != nil {
log.Fatal(err)
}
fmt.Println("Docs: ", insertResult.InsertedIDs)
}
```
## FindOneDoc
```go=
var problem Problem
filter := bson.M {"pid" : number}
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
err := collection.FindOne(ctx, filter).Decode(&problem)
if err != nil {
log.Fatal(err)
}
```
* BSON Objects
* Binary-encoded JSON
* Type :
* D: A BSON document. This type should be used in situations where order matters, such as MongoDB commands.
* M: An unordered map. It is the same as D, except it does not preserve order.
* A: A BSON array.
* E: A single element inside a D.
## FindAllDocs
```go=
findOptions := options.Find()
findOptions.SetLimit(10)
var results []*Problem
cur, err := collection.Find(context.TODO(), bson.D{{}}, findOptions)
if err != nil {
log.Fatal(err)
}
for cur.Next(context.TODO()) {
var elem Problem
err := cur.Decode(&elem)
if err != nil {
log.Fatal(err)
}
results = append(results, &elem)
}
if err := cur.Err(); err != nil {
log.Fatal(err)
}
```
* More Links
* [func (*Collection) Find](https://godoc.org/go.mongodb.org/mongo-driver/mongo#Connect)
## Reference
* [GitHub : MongoDB Go Driver](https://github.com/mongodb/mongo-go-driver)
* [Doc : MongoDB Go Driver](https://godoc.org/go.mongodb.org/mongo-driver/mongo)