Membuat upload dan download dengan golang graphql
2020/06/05
Sama seperti tulisan Membuat upload dan download dengan golang hanya kali ini kita membuatnya dengan graphql. Apakah bisa juga? Contoh kasus dalam dunia nyata seperti Upload foto, Import dan Export CSV dan lain lain.
Membuat Graphql Seerever Sederhana
Membuat graphql pada golang cukup mudah, kita bisa menggunakan library gqlgen. Instalasinya juga to the point bisa dibaca di Getting Started.
Intsall GQLGen
go get github.com/99designs/gqlgen
Inisialisasi kerangka kerja gqlgen
go run github.com/99designs/gqlgen init
Bikin Schema
type File {
id: ID!
text: String!
}
type Query {
file: [File!]!
}
input UploadInput {
text: String!
}
type Mutation {
singleUpload(input: UploadInput!): File!
}
Generate ulang schemanya
Ini adalah proses penulisan ulang kode resolver caranya tambahkan //go:generate go run github.com/99designs/gqlgen pada file resolver.go, letakan paling atas.
//go:generate go run github.com/99designs/gqlgen
package graph
// This file will not be regenerated automatically.
//
// It serves as dependency injection for your app, add any dependencies you require here.
type Resolver struct{}
lalu run
go generate ./...
untuk menjalakannya cukup dengan meruning file server.go
go run *.go
Sampai sini graphl server sudah run, kita sudah bisa test mutation query tapi karena belum diimplement kode apapun maka akan error.
mutation UploadFile {
singleUpload(input:{
text: "adasd",
}){
id
text
}
}
Menambahkan Fitur Upload
Tugas dari fungsi upload seperti ini:
- Membaca file yang diupload dari request yang diterima
- Membuat folder
temp - Menulis file kedalam folder
temp
Untuk membuat fitur upload, kita perlu mengubah schema.
scalar Upload
type File {
id: ID!
text: String!
}
type Query {
files: [File!]!
}
type Mutation {
singleUpload(file: Upload!): File!
}
Perubahan terdapat pada argumen muatation, singleUpload(file: Upload!): File!.
Kita menggunakan scalar Upload. Lalu generate ulang. Sehingga menghasilkan code seperti ini.
func (r *mutationResolver) SingleUpload(ctx context.Context, file graphql.Upload) (*model.File, error) {
folderPath := "./temp"
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
_ = os.MkdirAll(folderPath, os.ModePerm)
}
// Tulis file kedalam folder temp
name := filepath.Join("temp", file.Filename)
temp, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if err != nil {
return &model.File{}, err
}
defer temp.Close()
filesByte, err := ioutil.ReadAll(file.File)
if err != nil {
return &model.File{}, err
}
_, _ = temp.Write(filesByte)
return &model.File{}, nil
}
Scalar Upload akan menhasilkan file graphql.Upload. yang isinya adalah struct berisi io.Reader sehingga file bisa kita baca.
Kita test, asumsi kita menjalakan curl dibawah berada diroot project dan coba upload file server.go:
curl localhost:8080/query \
-F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }' \
-F map='{ "0": ["variables.file"] }' \
-F 0=@server.go
Selesai.
Referensi: