Khi định nghĩa API specs với RAML, việc chúng ta định nghĩa tất cả các thông tin chỉ trong một tập tin RAML sẽ gây khó khăn trong việc maintain và sẽ có những phần, những data types được sử dụng đi, sử dụng lại trong nhiều request URI khác nhau, nếu định nghĩa như vậy thì không phải là best practice. Việc chia nhỏ định nghĩa những phần được sử dụng đi sử dụng lại này thành những fragments trong những tập tin RAML khác, sẽ giúp chúng ta quản lý cách định nghĩa API specs tốt hơn, tránh lặp đi lại những thứ không cần thiết. Trong bài viết này, mình sẽ hướng dẫn các bạn cách định nghĩa API specs với các fragments trong RAML các bạn nhé!
Để làm ví dụ cho bài viết này, mình sẽ sử dụng một tập tin RAML định nghĩa API specs dùng để quản lý thông tin sinh viên có nội dung ban đầu như sau:
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 |
#%RAML 1.0 baseUri: https://localhost:8081/api title: Student Information Management System version: 1.0 types: Student: type: object properties: id?: type: integer example: 1 code: type: string example: "001" name: type: string example: "Huong Dan Java" /students: get: responses: 200: body: application/json: type: array items: Student example: [ { "id": 1, "code": "001", "name": "Khanh" }, { "id": 2, "code": "002", "name": "Quan" } ] post: body: application/json: type: Student example: { "code": "005", "name": "Khanh" } /{id}: uriParameters: id: description: Id of the Student type: string example: "1" get: responses: 200: body: application/json: example: { "id": 1, "code": "001", "name": "Khanh" } put: body: application/json: type: Student example: { "id": 5, "code": "005", "name": "Khanh Nguyen" } delete: responses: 200: body: application/json: example: { "message": "Student deleted!" } |
Như các bạn thấy là, tất cả các thông tin về Student object, các example đều được khai báo trong cùng một tập tin RAML. Giả sử sau này ứng dụng của mình được mở rộng để thêm các request URI thêm xoá sửa lớp học, lấy thông tin student của một lớp học:
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 |
#%RAML 1.0 baseUri: https://localhost:8081/api title: Student Information Management System version: 1.0 types: Student: type: object properties: id?: type: integer example: 1 code: type: string example: "001" name: type: string example: "Huong Dan Java" Clazz: type: object properties: id?: type: integer example: 1 name: type: string example: "A" students?: type: array items: Student /students: get: responses: 200: body: application/json: type: array items: Student example: [ { "id": 1, "code": "001", "name": "Khanh" }, { "id": 2, "code": "002", "name": "Quan" } ] post: body: application/json: type: Student example: { "code": "005", "name": "Khanh" } /{id}: uriParameters: id: description: Id of the Student type: string example: "1" get: responses: 200: body: application/json: example: { "id": 1, "code": "001", "name": "Khanh" } put: body: application/json: type: Student example: { "id": 5, "code": "005", "name": "Khanh Nguyen" } delete: responses: 200: body: application/json: example: { "message": "Student deleted!" } /classes: get: responses: 200: body: application/json: type: array items: Clazz example: [{ "id": 1, "name": "A" }, { "id": 2, "name": "B" }] post: body: application/json: type: Clazz example: { "name": "A" } /{id}: uriParameters: id: description: Id of the Class type: string example: "1" get: responses: 200: body: application/json: type: Clazz example: { "id": 1, "name": "A" } put: body: application/json: type: Clazz example: { "id": 5, "name": "B" } delete: responses: 200: body: application/json: example: { "message": "Class deleted!" } /students: get: responses: 200: body: application/json: type: Clazz example: { "id": 1, "name": "A", "students": [ { "id": 1, "code": "001", "name": "Khanh" }, { "id": 2, "code": "002", "name": "Quan" } ] } |
thì như các bạn thấy: nội dung của tập tin RAML này sẽ phình ra nhiều hơn gây khó khăn trong việc chỉnh sửa, các example không được reusable, … Sử dụng các fragments sẽ giúp chúng ta giải quyết những bất cập này.
Để sử dụng các fragments, điều các bạn cần phải làm đó là chia nhỏ tập tin RAML của chúng ta (mình sẽ gọi tập tin RAML này là tập tin root RAML các bạn nhé!) bằng cách định nghĩa fragment cho các data types, các thông tin chung giữa các request URI sử dụng các tập tin RAML khác và khai báo để sử dụng những tập tin RAML này trong tập tin root RAML sử dụng từ khoá “!include”.
Trong ví dụ của mình ở trên thì việc đầu tiên chúng ta có thể làm là định nghĩa fragment cho các data type object trong các tập tin RAML khác.
Mình sẽ tạo mới 2 tập tin student.raml và class.raml nằm trong thư mục data-types/objects:
để định nghĩa data type cho các object Student, Class.
Để định nghĩa fragment cho các data type, chúng ta cần khai báo dòng “#%RAML 1.0 DataType” ở đầu của mỗi tập tin .raml. Ví dụ nội dung của tập tin student.raml sẽ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#%RAML 1.0 DataType displayName: Student properties: id?: type: integer example: 1 code: type: string example: "001" name: type: string example: "Huong Dan Java" |
Trong tập tin class.raml, chúng ta sẽ sử dụng từ khoá “!include” để khai báo cho Student object như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#%RAML 1.0 DataType displayName: Class properties: id: type: integer example: 1 name: type: string example: "A" students: type: array items: !include student.raml |
Bây giờ thì trong tập tin root RAML, chúng ta không cần khai báo các data type object nữa. Chúng ta chỉ cần sử dụng từ khoá “!include”, ví dụ như sau:
1 2 3 |
types: Student: !include data-types/objects/student.raml Clazz: !include data-types/objects/class.raml |
Cho các example thì chúng ta có thể tạo thư mục examples để chứa các example này:
Lúc này thì các bạn có thể khai báo example trong tập tin root RAML ví dụ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/students: ... /{id}: uriParameters: id: description: Id of the Student type: string example: "1" get: responses: 200: body: application/json: type: Student example: !include examples/student.json |
Nội dung tập tin root RAML của chúng ta sau khi sử dụng fragment chỉ còn lại như sau:
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 |
#%RAML 1.0 baseUri: https://localhost:8081/api title: Student Information Management System version: 1.0 types: Student: !include data-types/objects/student.raml Clazz: !include data-types/objects/class.raml /students: get: responses: 200: body: application/json: type: array items: Student example: !include examples/students.json post: body: application/json: type: Student example: !include examples/post-student.json /{id}: uriParameters: id: description: Id of the Student type: string example: "1" get: responses: 200: body: application/json: type: Student example: !include examples/student.json put: body: application/json: type: Student example: !include examples/student.json delete: responses: 200: body: application/json: example: { "message": "Student deleted!" } /classes: get: responses: 200: body: application/json: type: array items: Clazz example: !include examples/classes.json post: body: application/json: type: Clazz example: !include examples/post-class.json /{id}: uriParameters: id: description: Id of the Class type: string example: "1" get: responses: 200: body: application/json: type: Clazz example: !include examples/class.json put: body: application/json: type: Clazz example: !include examples/class.json delete: responses: 200: body: application/json: example: { "message": "Class deleted!" } /students: get: responses: 200: body: application/json: type: Clazz example: !include examples/class-with-students.json |