source: binary-improvements2/WebServer/src/WebAPI/AbsRestApi.cs@ 392

Last change on this file since 392 was 391, checked in by alloc, 2 years ago

Major refactoring/cleanup

File size: 5.1 KB
Line 
1using System;
2using System.IO;
3using System.Net;
4using AllocsFixes.JSON;
5
6namespace Webserver.WebAPI {
7 public abstract class AbsRestApi : AbsWebAPI {
8 public sealed override void HandleRequest (RequestContext _context) {
9 JsonNode jsonBody = null;
10
11 if (_context.Request.HasEntityBody) {
12 string body = new StreamReader (_context.Request.InputStream).ReadToEnd ();
13
14 if (!string.IsNullOrEmpty (body)) {
15 try {
16 jsonBody = Parser.Parse (body);
17 } catch (Exception e) {
18 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "INVALID_BODY", e);
19 return;
20 }
21 }
22 }
23
24 try {
25 switch (_context.Request.HttpMethod) {
26 case "GET":
27 if (jsonBody != null) {
28 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "GET_WITH_BODY");
29 return;
30 }
31
32 HandleRestGet (_context);
33 return;
34 case "POST":
35 if (!string.IsNullOrEmpty (_context.RequestPath)) {
36 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "POST_WITH_ID");
37 return;
38 }
39
40 if (jsonBody == null) {
41 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "POST_WITHOUT_BODY");
42 return;
43 }
44
45 HandleRestPost (_context, jsonBody);
46 return;
47 case "PUT":
48 if (string.IsNullOrEmpty (_context.RequestPath)) {
49 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "PUT_WITHOUT_ID");
50 return;
51 }
52
53 if (jsonBody == null) {
54 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "PUT_WITHOUT_BODY");
55 return;
56 }
57
58 HandleRestPut (_context, jsonBody);
59 return;
60 case "DELETE":
61 if (string.IsNullOrEmpty (_context.RequestPath)) {
62 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "DELETE_WITHOUT_ID");
63 return;
64 }
65
66 if (jsonBody != null) {
67 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "DELETE_WITH_BODY");
68 return;
69 }
70
71 HandleRestDelete (_context);
72 return;
73 default:
74 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "INVALID_METHOD");
75 return;
76 }
77 } catch (Exception e) {
78 SendEnvelopedResult (_context, null, HttpStatusCode.InternalServerError, jsonBody, "ERROR_PROCESSING", e);
79 }
80 }
81
82 private static readonly JsonArray emptyData = new JsonArray ();
83
84 protected void SendEnvelopedResult (RequestContext _context, JsonNode _resultData, HttpStatusCode _statusCode = HttpStatusCode.OK,
85 JsonNode _jsonInputBody = null, string _errorCode = null, Exception _exception = null) {
86 JsonObject meta = new JsonObject ();
87
88 meta.Add ("serverTime", new JsonString (DateTime.Now.ToString ("o")));
89 if (!string.IsNullOrEmpty (_errorCode)) {
90 meta.Add ("requestMethod", new JsonString (_context.Request.HttpMethod));
91 meta.Add ("requestSubpath", new JsonString (_context.RequestPath));
92 meta.Add ("requestBody", new JsonString (_jsonInputBody?.ToString () ?? "-empty-"));
93 meta.Add ("errorCode", new JsonString (_errorCode));
94 if (_exception != null) {
95 meta.Add ("exceptionMessage", new JsonString (_exception.Message));
96 meta.Add ("exceptionTrace", new JsonString (_exception.StackTrace));
97 }
98 }
99
100 JsonObject envelope = new JsonObject ();
101 envelope.Add ("meta", meta);
102 envelope.Add ("data", _resultData ?? emptyData);
103
104 WebUtils.WriteJson (_context.Response, envelope, _statusCode);
105 }
106
107 protected bool TryGetJsonField (JsonObject _jsonObject, string _fieldName, out int _value) {
108 _value = default;
109
110 if (!_jsonObject.TryGetValue (_fieldName, out JsonNode fieldNode)) {
111 return false;
112 }
113
114 if (!(fieldNode is JsonValue valueField)) {
115 return false;
116 }
117
118 try {
119 _value = valueField.AsInt;
120 return true;
121 } catch (Exception) {
122 return false;
123 }
124 }
125
126 protected bool TryGetJsonField (JsonObject _jsonObject, string _fieldName, out double _value) {
127 _value = default;
128
129 if (!_jsonObject.TryGetValue (_fieldName, out JsonNode fieldNode)) {
130 return false;
131 }
132
133 if (!(fieldNode is JsonValue valueField)) {
134 return false;
135 }
136
137 try {
138 _value = valueField.AsDouble;
139 return true;
140 } catch (Exception) {
141 return false;
142 }
143 }
144
145 protected bool TryGetJsonField (JsonObject _jsonObject, string _fieldName, out string _value) {
146 _value = default;
147
148 if (!_jsonObject.TryGetValue (_fieldName, out JsonNode fieldNode)) {
149 return false;
150 }
151
152 if (!(fieldNode is JsonValue valueField)) {
153 return false;
154 }
155
156 try {
157 _value = valueField.AsString;
158 return true;
159 } catch (Exception) {
160 return false;
161 }
162 }
163
164 protected abstract void HandleRestGet (RequestContext _context);
165
166 protected abstract void HandleRestPost (RequestContext _context, JsonNode _jsonBody);
167
168 protected abstract void HandleRestPut (RequestContext _context, JsonNode _jsonBody);
169
170 protected abstract void HandleRestDelete (RequestContext _context);
171 }
172}
Note: See TracBrowser for help on using the repository browser.