Using couchbase Server in A golang Web application

Source: Internet
Author: User
Tags couchbase
This is a creation in Article, where the information may have evolved or changed.




    • Using the Couchbase database in the Go web App
      • Body
        • Create a new project with a dependency packet
        • Configuring Couchbase Services for Golang Engineering
        • Designing RESTful Web Apps
      • Conclusion
      • Words





Using the Couchbase database in the Go web App



Date: 2016-08-05
Author: Nic Raboy
Original: https://www.thepolyglotdeveloper.com/2016/08/using-couchbase-server-golang-web-application/?utm_source= Tuicool&utm_medium=referral
A Flower and a world
Date: 2016-09-11
Typography: The Mark Flying Elephant (Https://maxiang.io)


Translation Preface
I translate according to the original text, in the process of feeling some common words difficult to express with simple words, understand that translation is not easy.
If there is any improper, please advise, I will be updated in time.
In addition, I also attached the new words to the text, after the main translation of the technical articles on the Go language, mainly short-based.


Body



Not long ago I wrote an article about how to build a restful API with the go language, but that article used only analog data rather than a real database. What if you use a real database in the go language? What database to use, or more importantly, which type of database to choose? Most APIs are transmitted in JSON format, so the same format is used for data storage. This means that the relational database may not be available. In contrast, NoSQL data works well for restful APIs. In a database that stores data in JSON format, it is popular to have an open-source database called Couchbase.



Let's look at the use of couchbase in the go language to develop restful web apps.



The previous article is the basis of this article example, so if you have not seen it, I highly recommend you to see.
If you don't go and see what I'm saying here, you may be confused.



Also, assume that the go language is installed and configured on your machine.



Create a new project with a dependency packet



For simplicity's sake, we'll create a new project. Using the (Mac and Linux) terminal or the command line (Windows), execute the following statement



Create a new Go project


$GOPATH/src/github.com/nraboy/cbproject


In fact, I have already created the above directory with the command, and if your system doesn't take effect, create it manually.



In the project catalog, there is a file in Main.go, which is also the only one in the work. Before you start coding, it's a good idea to download a dependency package in your project.



At the command line or terminal, do the following:
Get the extended dependency package


go get github.com/satori/go.uuidgo get github.com/couchbase/gocbgo get github.com/gorilla/mux


The dependency package contains a package that generates a UUID value, which is used to generate the IDs for the document; The SDK for Couchbase Go, a mux to increase the routing capability of the HTTP server.



Configuring Couchbase Services for Golang Engineering



Determine if the Couchbase configuration is available before you begin coding. Don't say how to install couchbase here. If you're using a Mac, Linux, or Windows machine, you can take a look at getting started with the installation tutorial. Now configure a bucket name in our app that can store NoSQL documents.



Now the goal is to create a couchbase bucket name named Restful-sample for the application, which has an appropriate index for executing the N1QL query.



In Couchbase's administrator interface, select Data Buckets, and then select Create New Data Bucket. Give the bucket a name and define the size of a storage space.



Create a bucket in couchbase



Next, I'll create an index for the new bucket.



When it comes to creating an index, there are a number of ways to achieve it. If Couchbase 4.5 or above, you can use the query Workbench. Execute the following query in Query Workbench:



Create a primary index for N1QL queries


CREATE PRIMARY INDEX onrestful-sampleUSING GSI;





Use N1QL to have at least one index. A more complex index than I have shown here will make the query faster.



Creating a primary index in Couchbase



If you do not have couchbase4.5 or higher installed, another method is to create an index. You can use Couchbase Query Shell (CBQ), which comes with Couchbase 4.0 or higher. Information about how to use these can be accessed here. can be used in Query workbench, or in the shell.



Here, the focus is on practical applications.



Designing RESTful Web Apps



Once the above configuration is done, you can write the code. This app has five basic sides to handle information about "people".



In the project $GOPATH/src/github.com/nraboy/cbproject/main.go file, add the following code:


$GOPATH/src/github.com/nraboy/cbproject/main.go

 
package main import ( "encoding/json" "log" "net/http" "github.com/couchbase/gocb" "github.com/gorilla/mux" "github.com/satori/go.uuid" ) type Person struct {
    ID string `json:"id,omitempty"` Firstname string `json:"firstname,omitempty"` Lastname string `json:"lastname,omitempty"` Email string `json:"email,omitempty"` } type N1qlPerson struct {
    Person Person `json:"person"` } var bucket *gocb.Bucket func GetPersonEndpoint(w http.ResponseWriter, req *http.Request) { var n1qlParams []interface{}
    query := gocb.NewN1qlQuery("SELECT * FROM `restful-sample` AS person WHERE META(person).id = $1")
    params := mux.Vars(req)
    n1qlParams = append(n1qlParams, params["id"])
    rows, _ := bucket.ExecuteN1qlQuery(query, n1qlParams) var row N1qlPerson
    rows.One(&row)
    json.NewEncoder(w).Encode(row.Person)
} func GetPeopleEndpoint(w http.ResponseWriter, req *http.Request) { var person []Person
    query := gocb.NewN1qlQuery("SELECT * FROM `restful-sample` AS person")
    rows, _ := bucket.ExecuteN1qlQuery(query, nil) var row N1qlPerson for rows.Next(&row) {
        person = append(person, row.Person)
    }
    json.NewEncoder(w).Encode(person)
} func CreatePersonEndpoint(w http.ResponseWriter, req *http.Request) { var person Person var n1qlParams []interface{}
    _ = json.NewDecoder(req.Body).Decode(&person)
    query := gocb.NewN1qlQuery("INSERT INTO `restful-sample` (KEY, VALUE) VALUES ($1, {'firstname': $2, 'lastname': $3, 'email': $4})")
    n1qlParams = append(n1qlParams, uuid.NewV4().String())
    n1qlParams = append(n1qlParams, person.Firstname)
    n1qlParams = append(n1qlParams, person.Lastname)
    n1qlParams = append(n1qlParams, person.Email)
    _, err := bucket.ExecuteN1qlQuery(query, n1qlParams) if err != nil {
        w.WriteHeader(401)
        w.Write([]byte(err.Error())) return }
    json.NewEncoder(w).Encode(person)
} func UpdatePersonEndpoint(w http.ResponseWriter, req *http.Request) { var person Person var n1qlParams []interface{}
    _ = json.NewDecoder(req.Body).Decode(&person)
    query := gocb.NewN1qlQuery("UPDATE `restful-sample` USE KEYS $1 SET firstname = $2, lastname = $3, email = $4")
    params := mux.Vars(req)
    n1qlParams = append(n1qlParams, params["id"])
    n1qlParams = append(n1qlParams, person.Firstname)
    n1qlParams = append(n1qlParams, person.Lastname)
    n1qlParams = append(n1qlParams, person.Email)
    _, err := bucket.ExecuteN1qlQuery(query, n1qlParams) if err != nil {
        w.WriteHeader(401)
        w.Write([]byte(err.Error())) return }
    json.NewEncoder(w).Encode(person)
} func DeletePersonEndpoint(w http.ResponseWriter, req *http.Request) { var n1qlParams []interface{}
    query := gocb.NewN1qlQuery("DELETE FROM `restful-sample` AS person WHERE META(person).id = $1")
    params := mux.Vars(req)
    n1qlParams = append(n1qlParams, params["id"])
    _, err := bucket.ExecuteN1qlQuery(query, n1qlParams) if err != nil {
        w.WriteHeader(401)
        w.Write([]byte(err.Error())) return }
    json.NewEncoder(w).Encode(&Person{})
} func main() {
    router := mux.NewRouter()
    cluster, _ := gocb.Connect("couchbase://localhost")
    bucket, _ = cluster.OpenBucket("restful-sample", "")
    router.HandleFunc("/people", GetPeopleEndpoint).Methods("GET")
    router.HandleFunc("/people/{id}", GetPersonEndpoint).Methods("GET")
    router.HandleFunc("/people", CreatePersonEndpoint).Methods("PUT")
    router.HandleFunc("/people/{id}", UpdatePersonEndpoint).Methods("POST")
    router.HandleFunc("/people/{id}", DeletePersonEndpoint).Methods("DELETE")
    log.Fatal(http.ListenAndServe(":12345", router))
}


There's a lot of functionality in the code above, and it's a good idea to take it apart.



First, we import a variety of dependency packages, which are mentioned earlier. With the package contained in this project, we can define two structures, one representing the JSON data, and we use it to work. The person structure contains the necessary information for the person, which will present the database in the form of JSON. When querying data, the result set is presented as an object of the parent JSON, which is required for the N1qlperson structure. The query results look like this:



JSON Data from Queries


{
    "person": {
        "id": "1234",
        "firstname": "Nic",
        "lastname": "Raboy",
        "email": "nic@test.com" } }


In this structure, pay attention to the use of omitempty tags. This means that if a property is an empty value, it will not appear in the JSON results.
Before jumping to the end function, do the following:


$GOPATH/src/github.com/nraboy/cbproject/main.go

var bucket *gocb.Bucket


This bucket variable is defined outside the main function and is a global variable. It is used when querying data and opening couchbase buckets.



Jump to the main function of the project:
$GOPATH/src/github.com/nraboy/cbproject/main.go


 
func main() {
    router := mux.NewRouter()
    cluster, _ := gocb.Connect("couchbase://localhost")
    bucket, _ = cluster.OpenBucket("restful-sample", "")
    router.HandleFunc("/people", GetPeopleEndpoint).Methods("GET")
    router.HandleFunc("/people/{id}", GetPersonEndpoint).Methods("GET")
    router.HandleFunc("/people", CreatePersonEndpoint).Methods("PUT")
    router.HandleFunc("/people/{id}", UpdatePersonEndpoint).Methods("POST")
    router.HandleFunc("/people/{id}", DeletePersonEndpoint).Methods("DELETE")
    log.Fatal(http.ListenAndServe(":12345", router))
}


The main function above defines the routing of the application and establishes a connection to the Couchbase cluster. In this case, the Couchbase cluster is running locally on our machine. When a couchbase cluster connection is established, a bucket can be opened. Here This bucket is called the restful-sample.



There are five different routes here. One is to get all the documents, one to get a single document, one to create a document, one to update, and the last to delete. Note that each of these routes uses get, PUT, POST, or DELETE. Let's look at each end function that matches it.


$GOPATH/src/github.com/nraboy/cbproject/main.go

 
func GetPersonEndpoint(w http.ResponseWriter, req *http.Request) { var n1qlParams []interface{}
    query := gocb.NewN1qlQuery("SELECT * FROM `restful-sample` AS person WHERE META(person).id = $1")
    params := mux.Vars(req)
    n1qlParams = append(n1qlParams, params["id"])
    rows, _ := bucket.ExecuteN1qlQuery(query, n1qlParams) var row N1qlPerson
    rows.One(&row)
    json.NewEncoder(w).Encode(row.Person)
}


The Getpersonendpoint function above takes a single-person record from the database. The ID in the meta-information is compared to the ID from the routing request. This query is a parameterized query that prevents SQL injection. We return the JSON data, which is only the structure of the person, not the entire N1plperson structure.


$GOPATH/src/github.com/nraboy/cbproject/main.go

 
func GetPeopleEndpoint(w http.ResponseWriter, req *http.Request) { var person []Person
    query := gocb.NewN1qlQuery("SELECT * FROM `restful-sample` AS person")
    rows, _ := bucket.ExecuteN1qlQuery(query, nil) var row N1qlPerson for rows.Next(&row) {
        person = append(person, row.Person)
    }
    json.NewEncoder(w).Encode(person)
}


The above Getpeopleendpoint function is similar to the previous one, but this time the result is expected to be a slice rather than a single structure.



Create, update, and delete functions are almost as basic as above, making maintenance and understanding easy.



At this point, the application can run. It can be tested with curl, postman, and the Web browser does not provide ready-made tools to test put, POST, or DELETE.



Conclusion



You just saw that by using Couchbase as a NoSQL database, the previous example of the RESTful API go language was used in more depth. When using the Couchbase database, we use a class SQL query called N1QL to query the data, which makes coding easier and also reduces many potential syntax errors.



Words


    1. When it comes to doing
    2. Out of the The by
    3. At this point
    4. A lot going on
    5. Particular a certain
    6. Go with
    7. Meta information
    8. Being compared agains
    9. Prevent SQL Injection
    10. Out of the box
    11. Potential
    12. Mock data
    13. Make sense to
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.