Skip to content

Commit 39e69f5

Browse files
committed
Implement WRITE API
1 parent cc0c8c1 commit 39e69f5

File tree

5 files changed

+345
-161
lines changed

5 files changed

+345
-161
lines changed

client.go

+42-134
Original file line numberDiff line numberDiff line change
@@ -1,177 +1,85 @@
11
package microcms
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"fmt"
7+
"io/ioutil"
68
"net/http"
79
"net/url"
810
"strings"
911
)
1012

13+
type httpClient interface {
14+
Do(req *http.Request) (*http.Response, error)
15+
}
16+
1117
type Client struct {
1218
serviceDomain string
1319
apiKey string
20+
httpClient httpClient
1421
}
1522

16-
type Params struct {
17-
contentID string
18-
draftKey string
19-
limit int
20-
offset int
21-
orders []string
22-
q string
23-
fields []string
24-
ids []string
25-
filters string
26-
depth int
27-
}
28-
29-
type RequestParams func(*Params)
30-
31-
func CreateClient(serviceDomain, apiKey string) *Client {
23+
func New(serviceDomain, apiKey string) *Client {
3224
c := &Client{
3325
serviceDomain: serviceDomain,
3426
apiKey: apiKey,
27+
httpClient: http.DefaultClient,
3528
}
3629
return c
3730
}
3831

39-
func (c *Client) makeRequest(method, endpoint string, p *Params) (*http.Request, error) {
40-
url := createURL(c.serviceDomain, endpoint, p)
41-
42-
req, err := http.NewRequest(http.MethodGet, url, nil)
43-
if err != nil {
44-
return nil, err
45-
}
46-
47-
req.Header.Set("X-MICROCMS-API-KEY", c.apiKey)
48-
49-
return req, nil
32+
func (c *Client) SetHTTPClient(client *http.Client) {
33+
c.httpClient = client
5034
}
5135

52-
func (c *Client) Get(endpoint string, data interface{}, params ...RequestParams) error {
53-
p := &Params{}
54-
for _, params := range params {
55-
params(p)
36+
func makeRequest(c *Client, method, endpoint string, query url.Values, data interface{}) (*http.Request, error) {
37+
url := fmt.Sprintf("https://%s.%s/api/%s/%s", c.serviceDomain, BaseDomain, APIVersion, endpoint)
38+
if len(query) > 0 {
39+
url = fmt.Sprintf("%s?%s", url, query.Encode())
5640
}
5741

58-
req, err := c.makeRequest(http.MethodGet, endpoint, p)
59-
if err != nil {
60-
return err
42+
buf := new(bytes.Buffer)
43+
if data != nil {
44+
if err := json.NewEncoder(buf).Encode(data); err != nil {
45+
return nil, err
46+
}
6147
}
6248

63-
res, err := http.DefaultClient.Do(req)
49+
req, err := http.NewRequest(method, url, buf)
6450
if err != nil {
65-
return err
66-
}
67-
defer res.Body.Close()
68-
69-
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
70-
return err
71-
}
72-
73-
return err
74-
}
75-
76-
func createURL(serviceDomain, endpoint string, p *Params) string {
77-
base := fmt.Sprintf("https://%s.%s/api/%s/%s", serviceDomain, BaseDomain, APIVersion, endpoint)
78-
79-
if p.contentID != "" {
80-
base = fmt.Sprintf("%s/%s", base, p.contentID)
81-
}
82-
83-
urlValues := url.Values{}
84-
if len(p.draftKey) > 0 {
85-
urlValues.Set("draftKey", p.draftKey)
86-
}
87-
if p.limit != 0 {
88-
urlValues.Set("limit", fmt.Sprint(p.limit))
89-
}
90-
if p.offset != 0 {
91-
urlValues.Set("offset", fmt.Sprint(p.offset))
92-
}
93-
if len(p.orders) > 0 {
94-
urlValues.Set("orders", strings.Join(p.orders, ","))
95-
}
96-
if len(p.q) > 0 {
97-
urlValues.Set("q", p.q)
98-
}
99-
if len(p.fields) > 0 {
100-
urlValues.Set("fields", strings.Join(p.fields, ","))
101-
}
102-
if len(p.ids) > 0 {
103-
urlValues.Set("ids", strings.Join(p.ids, ","))
104-
}
105-
if len(p.filters) > 0 {
106-
urlValues.Set("filters", p.filters)
107-
}
108-
if p.depth != 0 {
109-
urlValues.Set("depth", fmt.Sprint(p.depth))
110-
}
111-
112-
if len(urlValues) > 0 {
113-
base = fmt.Sprintf("%s?%s", base, urlValues.Encode())
114-
}
115-
116-
return base
117-
}
118-
119-
func ContentID(v string) RequestParams {
120-
return func(p *Params) {
121-
p.contentID = v
122-
}
123-
}
124-
125-
func DraftKey(v string) RequestParams {
126-
return func(p *Params) {
127-
p.draftKey = v
128-
}
129-
}
130-
131-
func Limit(v int) RequestParams {
132-
return func(p *Params) {
133-
p.limit = v
51+
return nil, err
13452
}
135-
}
13653

137-
func Offset(v int) RequestParams {
138-
return func(p *Params) {
139-
p.offset = v
140-
}
141-
}
54+
req.Header.Set("X-MICROCMS-API-KEY", c.apiKey)
14255

143-
func Orders(v []string) RequestParams {
144-
return func(p *Params) {
145-
p.orders = v
56+
if data != nil {
57+
req.Header.Set("Content-Type", "application/json; charset=utf-8")
14658
}
147-
}
14859

149-
func Q(v string) RequestParams {
150-
return func(p *Params) {
151-
p.q = v
152-
}
60+
return req, nil
15361
}
15462

155-
func Fields(v []string) RequestParams {
156-
return func(p *Params) {
157-
p.fields = v
63+
func sendRequest(c *Client, req *http.Request, data interface{}) error {
64+
res, err := c.httpClient.Do(req)
65+
if err != nil {
66+
return err
15867
}
159-
}
68+
defer res.Body.Close()
16069

161-
func IDs(ids []string) RequestParams {
162-
return func(p *Params) {
163-
p.ids = ids
70+
if res.StatusCode >= 400 {
71+
errorMessage, err := ioutil.ReadAll(res.Body)
72+
if err != nil {
73+
return fmt.Errorf("microCMS connection error: %w", err)
74+
}
75+
return fmt.Errorf("microCMS response error: %s", errorMessage)
16476
}
165-
}
16677

167-
func Filters(v string) RequestParams {
168-
return func(p *Params) {
169-
p.filters = v
78+
if strings.Contains(res.Header.Get("Content-Type"), "application/json") {
79+
if err := json.NewDecoder(res.Body).Decode(data); err != nil {
80+
return err
81+
}
17082
}
171-
}
17283

173-
func Depth(v int) RequestParams {
174-
return func(p *Params) {
175-
p.depth = v
176-
}
84+
return nil
17785
}

constants.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package microcms
22

33
// Base API endpoint
44
const (
5-
BaseDomain = "microcms.io"
6-
APIVersion = "v1"
5+
BaseDomain = "microcms.io"
6+
APIVersion = "v1"
7+
StatusDraft = "draft"
78
)

create.go

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package microcms
2+
3+
import (
4+
"net/http"
5+
"net/url"
6+
"path"
7+
)
8+
9+
type CreateParams struct {
10+
Endpoint string
11+
ContentID string
12+
Status string
13+
Content interface{}
14+
}
15+
16+
type UpdateParams struct {
17+
Endpoint string
18+
ContentID string
19+
Content interface{}
20+
}
21+
22+
type DeleteParams struct {
23+
Endpoint string
24+
ContentID string
25+
}
26+
27+
type CreateResponse struct {
28+
ID string
29+
}
30+
31+
type UpdateResponse struct {
32+
ID string
33+
}
34+
35+
func (c *Client) Create(p CreateParams) (*CreateResponse, error) {
36+
var reqMethod, reqPath string
37+
if len(p.ContentID) > 0 {
38+
reqMethod = http.MethodPut
39+
reqPath = path.Join(p.Endpoint, p.ContentID)
40+
} else {
41+
reqMethod = http.MethodPost
42+
reqPath = p.Endpoint
43+
}
44+
45+
req, err := makeRequest(c, reqMethod, reqPath, makeCreateQuery(p), p.Content)
46+
if err != nil {
47+
return nil, err
48+
}
49+
50+
res := new(CreateResponse)
51+
if err := sendRequest(c, req, res); err != nil {
52+
return nil, err
53+
}
54+
55+
return res, err
56+
}
57+
58+
func (c *Client) Update(p UpdateParams) (*UpdateResponse, error) {
59+
req, err := makeRequest(c, http.MethodPatch, path.Join(p.Endpoint, p.ContentID), url.Values{}, p.Content)
60+
if err != nil {
61+
return nil, err
62+
}
63+
64+
res := new(UpdateResponse)
65+
if err := sendRequest(c, req, res); err != nil {
66+
return nil, err
67+
}
68+
69+
return res, err
70+
}
71+
72+
func (c *Client) Delete(p DeleteParams) error {
73+
req, err := makeRequest(c, http.MethodDelete, path.Join(p.Endpoint, p.ContentID), url.Values{}, nil)
74+
if err != nil {
75+
return err
76+
}
77+
78+
if err := sendRequest(c, req, nil); err != nil {
79+
return err
80+
}
81+
82+
return err
83+
}
84+
85+
func makeCreateQuery(p CreateParams) url.Values {
86+
urlValues := url.Values{}
87+
88+
if len(p.Status) > 0 {
89+
urlValues.Set("status", p.Status)
90+
}
91+
92+
return urlValues
93+
}

0 commit comments

Comments
 (0)