-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdoc.go
210 lines (209 loc) · 6.43 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// Package apifaker can help you start a json api server in a fast way
//
// If you would like to start a simple json api server for testing front-end, apifaker could be a on your hand.
//
// No need of database, just create some json file, and write two line codes, then, everything is done, you can start implementing the happy(hope so) front-end features.
//
// ### Usage
// ----
// #### Add a directory
//
// `apifaker` need a directory to contain the api json files
//
// #### Add api files
//
// Rules:
//
// 1. `"resource_name"` string(required), resource name for this api route, you can take it as a table name when using database. `apifaker` assumes that resource name is plural.
//
// 1. "`has_many`" array(optional), every element must be a string of one of the other `"resource_name"`, if a resource's has_many is empty:
// 1. The response of `GET /collention/:id` and `GET /collention` will be insert the related resources.
// 2. The `DELETE /collention/:id` will also deleted the related resources.
//
// 1. "`has_one`" array(optional), rules are same as the `"has_many`" except every element must be singular and the response of `GET /collention/:id` and `GET /collention` will be only insert the a first-found object.
//
// 1. `"columns"` array(required), columuns for resource, support `"id" "name"`, `"type"`, `"regexp_pattern"`, `"unique"`
// 1. `"id"` must be a "number" as the first cloumn.
// 1. Every colmun must has at lest `"name"` and `"type"`.
// 3. `"type"` supports: `"boolean" "number" "string" "array" "object"`, these types will be used to check every item data.
// 4. `"regexp_pattern"` add regular expression for your string-type column, using internal `regexp` package, you could run `go doc regexp/syntax` to learn all syntax.
// 5. `"unique"`: set true(default false) to specify this column should be unique.
//
//
// 1. `"seed"` array(optional), lineitems for this resource, note that every lineitem of seeds should has columns descriped in `"columns"` array, otherwise, it will throw an non-nil error.
//
// Here is an example for users.json
//
// ```json
// {
// "resource_name": "users",
// "columns": [
// {
// "name": "id",
// "type": "number"
// },
// {
// "name": "name",
// "type": "string",
// "regexp_pattern": "[A-z]|[0-9]",
// "unique": true
// },
// {
// "name": "phone",
// "type": "string",
// "regexp_pattern": "^132",
// "unique": true
// },
// {
// "name": "age",
// "type": "number"
// }
// ],
// "current_id": 3,
// "seeds": [
// {
// "id": 1,
// "name": "Frank",
// "phone": "13213213213",
// "age": 22
// },
// {
// "id": 2,
// "name": "Antony",
// "phone": "13213213211",
// "age": 22
// },
// {
// "id": 3,
// "name": "Foci",
// "phone": "13213213212",
// "age": 22
// }
// ]
// }
// ```
//
// And books.json
//
// ```json
// {
// "resource_name": "books",
// "columns": [
// {
// "name": "id",
// "type": "number"
// },
// {
// "name": "title",
// "type": "string",
// "regexp_pattern": "[A-z]|[0-9]",
// "unique": true
// },
// {
// "name": "user_id",
// "type": "number"
// }
//
// ],
// "current_id": 3,
// "seeds": [
// {
// "id": 1,
// "title": "The Little Prince",
// "user_id": 1
// },
// {
// "id": 2,
// "title": "Life of Pi",
// "user_id": 2
// },
// {
// "id": 3,
// "title": "The Alchemist",
// "user_id": 1
// }
// ]
// }
// ```
//
// #### Creat a apifaker
//
// ```go
// // if there are any errors of directory or json file format, err will not be nil
// fakeApi, err := apifaker.NewWithApiDir("/path/to/your/fake_apis")
// ```
//
// And you can use it as a http.Handler to listen and serve on a port:
//
// ```go
// http.ListenAndServe("localhost:3000", fakeApi)
// ```
//
// Now almost everything is done, let's assume that we use the above examples of users.json and books.json for the `fakerApi`, then you have a list of restful apis for users and books:
//
// ```shell
// GET /users
// GET /users/:id
// POST /users
// PUT /users/:id
// PATCH /users/:id
// DELETE /users/:id
//
// GET /books
// GET /books/:id
// POST /books
// PUT /books/:id
// PATCH /books/:id
// DELETE /books/:id
// ```
//
// And this apis are really be able to manage the users resource, just like using database, what's more, it will validate every request using the rules defined in `"columns"`, in this example, rules are:
//
// 0. every request: resource with given id must exist.
// 1. name of users and books must be unique and users'name must contain A-Z or 0-9.
// 2. phone of users must has prefix "132".
// 3. every POST/PATH/PUT request of books: the user with given user_id must exist.
//
// In a word, it acts like a standard restful api server.
//
// #### Data persistence
//
// `apifaker` will save automatically the changes back to the json file once 24 hours and when you handlers panic something. On the other hand, you can save data manually:
//
// ```go
// fakeApi.SaveTofile()
// ```
//
// #### Mount to other mux
//
// Also, you can compose other mutex which implemneted `http.Handler` to the fakeApi
//
// ```go
// mux := http.NewServeMux()
// mux.HandleFunc("/greet", func(rw http.ResponseWriter, req *http.Request) {
// rw.WriteHeader(http.StatusOK)
// rw.Write([]byte("hello world"))
// })
//
// fakeApi.MountTo("/fake_api", mux)
// http.ListenAndServe("localhost:3000", fakeApi)
// ```
//
// Then, `/greet` will be available, at the same time, users and books apis will change to be:
//
// ```shell
// GET /fake_api/users
// GET /fake_api/users/:id
// POST /fake_api/users
// PUT /fake_api/users/:id
// PATCH /fake_api/users/:id
// DELETE /fake_api/users/:id
//
// GET /fake_api/books
// GET /fake_api/books/:id
// POST /fake_api/books
// PUT /fake_api/books/:id
// PATCH /fake_api/books/:id
// DELETE /fake_api/books/:id
// ```
package apifaker