You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We may also want to remove `index.md` and `template.md` at some point,
but keeping for now pending larger conversations about how
`docs/decisions/` should be structured.
Related to navapbc/template-infra#401
Copy file name to clipboardExpand all lines: template/docs/decisions/{{app_name}}/2022-09-27-connexion-replacement.md
+44-45Lines changed: 44 additions & 45 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,20 +14,20 @@ We aren't looking to move off of Flask at the moment as we feel that would be a
14
14
15
15
## Decision Drivers
16
16
17
-
* Connexion requires you to specify an OpenAPI spec but passes the request objects as the raw JSON. We currently use Pydantic to convert this into a Python object for additional validations & for ease of use, but this effectively means we need to define any models twice.
18
-
* Defining the OpenAPI specs first instead of defining the data models in code has often been more frustrating. While one goal of doing it this way was the ability to create mock endpoints while development is ongoing, this can also be easily handled by just making the endpoint return a static response in-code.
19
-
* Connexion's defaults for validation leave a lot to be desired. While we currently override these, it adds a lot of boilerplate to this template library, and isn't immediately obvious.
20
-
* Code first is recommended by Swagger when building internal APIs that need to be built quickly: https://swagger.io/blog/api-design/design-first-or-code-first-api-development/ which is often the case for our endpoints that aren't directly exposed to users.
17
+
- Connexion requires you to specify an OpenAPI spec but passes the request objects as the raw JSON. We currently use Pydantic to convert this into a Python object for additional validations & for ease of use, but this effectively means we need to define any models twice.
18
+
- Defining the OpenAPI specs first instead of defining the data models in code has often been more frustrating. While one goal of doing it this way was the ability to create mock endpoints while development is ongoing, this can also be easily handled by just making the endpoint return a static response in-code.
19
+
- Connexion's defaults for validation leave a lot to be desired. While we currently override these, it adds a lot of boilerplate to this template library, and isn't immediately obvious.
20
+
- Code first is recommended by Swagger when building internal APIs that need to be built quickly: https://swagger.io/blog/api-design/design-first-or-code-first-api-development/ which is often the case for our endpoints that aren't directly exposed to users.
* Good, because the documentation is immensely thorough, and does a great job of explaining all the customization options while providing sane defaults.
134
-
* Good, because you can [register custom error processors](https://apiflask.com/error-handling/#custom-error-response-processor) which would allow us to reuse and adapt our existing error processors - although it looks like the defaults are more sane - as all errors, not just the first get added to the error response.
135
-
* Good, because [authentication looks to be flexible](https://apiflask.com/authentication/), and allows you to define it as if you were writing the OpenAPI.
136
-
* Good, because the [API uses Marshmallow](https://apiflask.com/schema/) for its data schema, which is a [well-maintained library](https://github.com/marshmallow-code/marshmallow) - and additionally supports [Marshmallow Dataclass](https://apiflask.com/schema/#use-dataclass-as-data-schema) which is a wrapper that allows you to interact directly with dataclass objects which further improves runtime typing.
137
-
* Meh, because methods end up with several decorators, although you can [group route methods into classes](https://apiflask.com/usage/#use-class-based-views) and make them share decorators (eg. set the authentication decorator on the class).
138
-
* Bad, because APIFlask 1.0 only released in May 2022, with the first beta release about a year earlier, so the project is still somewhat young.
133
+
- Good, because the documentation is immensely thorough, and does a great job of explaining all the customization options while providing sane defaults.
134
+
- Good, because you can [register custom error processors](https://apiflask.com/error-handling/#custom-error-response-processor) which would allow us to reuse and adapt our existing error processors - although it looks like the defaults are more sane - as all errors, not just the first get added to the error response.
135
+
- Good, because [authentication looks to be flexible](https://apiflask.com/authentication/), and allows you to define it as if you were writing the OpenAPI.
136
+
- Good, because the [API uses Marshmallow](https://apiflask.com/schema/) for its data schema, which is a [well-maintained library](https://github.com/marshmallow-code/marshmallow) - and additionally supports [Marshmallow Dataclass](https://apiflask.com/schema/#use-dataclass-as-data-schema) which is a wrapper that allows you to interact directly with dataclass objects which further improves runtime typing.
137
+
- Meh, because methods end up with several decorators, although you can [group route methods into classes](https://apiflask.com/usage/#use-class-based-views) and make them share decorators (eg. set the authentication decorator on the class).
138
+
- Bad, because APIFlask 1.0 only released in May 2022, with the first beta release about a year earlier, so the project is still somewhat young.
139
139
140
140
141
141
### Flask OpenAPI3
@@ -205,11 +205,11 @@ if __name__ == "__main__":
205
205
206
206
</details>
207
207
208
-
* Good, because the API model definitions use Pydantic, which is a well-supported library we are already familiar with.
209
-
* Good, because the API definitions are minimal and pretty intuitive to read.
210
-
* Bad, because the documentation isn't fully detailed, and the errors that occur when trying to get the API running aren't very clear. In ~30 minutes of debugging, I hadn't figured out how to get the API to fully run.
211
-
* Bad, while it generates swagger docs, and can display example responses, it doesn't appear that you can specify example requests or parameters. This effectively makes Swagger unusable.
212
-
* Bad, because it appears that the library is primarily [maintained by one person](https://github.com/luolingchun/flask-openapi3/commits/master), and appears to still be going through early implementation fixes.
208
+
- Good, because the API model definitions use Pydantic, which is a well-supported library we are already familiar with.
209
+
- Good, because the API definitions are minimal and pretty intuitive to read.
210
+
- Bad, because the documentation isn't fully detailed, and the errors that occur when trying to get the API running aren't very clear. In ~30 minutes of debugging, I hadn't figured out how to get the API to fully run.
211
+
- Bad, while it generates swagger docs, and can display example responses, it doesn't appear that you can specify example requests or parameters. This effectively makes Swagger unusable.
212
+
- Bad, because it appears that the library is primarily [maintained by one person](https://github.com/luolingchun/flask-openapi3/commits/master), and appears to still be going through early implementation fixes.
213
213
214
214
### Flasgger
215
215
@@ -221,9 +221,9 @@ Note that Flasgger has several different ways to define the schema. This specifi
221
221
222
222
No example implementation as the ones presented in the docs didn't actually function out of the box.
223
223
224
-
* Good, because there is a lot of variety in how you set up your schema, although most require defining the JSON/YAML yourself.
225
-
* Bad, because the non-JSON/YAML approaches don't appear to be the main purpose of this API, and little documentation/examples exist regarding their usage.
226
-
* Bad, because it seems the approach for running using [Marshmallow for the schema](https://github.com/flasgger/flasgger#using-marshmallow-schemas) isn't valid anymore as the parameters that Flask takes in don't match the example. From reading various other docs, Flask seems to have had a major version update that changed it a bit in recent years, so that is likely the cause.
224
+
- Good, because there is a lot of variety in how you set up your schema, although most require defining the JSON/YAML yourself.
225
+
- Bad, because the non-JSON/YAML approaches don't appear to be the main purpose of this API, and little documentation/examples exist regarding their usage.
226
+
- Bad, because it seems the approach for running using [Marshmallow for the schema](https://github.com/flasgger/flasgger#using-marshmallow-schemas) isn't valid anymore as the parameters that Flask takes in don't match the example. From reading various other docs, Flask seems to have had a major version update that changed it a bit in recent years, so that is likely the cause.
227
227
228
228
### Flask Smorest
229
229
@@ -304,11 +304,11 @@ if __name__ == "__main__":
304
304
305
305
</details>
306
306
307
-
* Good, because the API uses Marshmallow for its data schema, which is a [well-maintained library](https://github.com/marshmallow-code/marshmallow) - it's in the same project.
308
-
* Good, because it is fairly straightforward and just seems to work as expected.
309
-
* Bad, because the documentation is pretty minimal beyond getting OpenAPI running. Seems like this is just an OpenAPI wrapper with no other additional features.
310
-
* Bad, because it is pretty barebones. It just sets up a swagger endpoint and does the object validation, but doesn't handle anything beyond that regarding authentication.
311
-
* Bad, because even the maintainers recognize it needs a [bit more work](https://github.com/apiflask/apiflask/discussions/14#discussioncomment-571898)
307
+
- Good, because the API uses Marshmallow for its data schema, which is a [well-maintained library](https://github.com/marshmallow-code/marshmallow) - it's in the same project.
308
+
- Good, because it is fairly straightforward and just seems to work as expected.
309
+
- Bad, because the documentation is pretty minimal beyond getting OpenAPI running. Seems like this is just an OpenAPI wrapper with no other additional features.
310
+
- Bad, because it is pretty barebones. It just sets up a swagger endpoint and does the object validation, but doesn't handle anything beyond that regarding authentication.
311
+
- Bad, because even the maintainers recognize it needs a [bit more work](https://github.com/apiflask/apiflask/discussions/14#discussioncomment-571898)
312
312
313
313
### APISpec
314
314
@@ -422,10 +422,10 @@ if __name__ == "__main__":
422
422
```
423
423
</details>
424
424
425
-
* Good, because the API uses Marshmallow for its data schema, which is a [well-maintained library](https://github.com/marshmallow-code/marshmallow) - it's in the same project.
426
-
* Good, because it gives a lot of flexibility for defining the OpenAPI docs, [including security](https://apispec.readthedocs.io/en/latest/special_topics.html#documenting-security-schemes).
427
-
* Bad, because you still have to specify some of the OpenAPI docs as a comment on the function. The primary gain is being able to use Marshmallow to define the schema models, but the routes are still largely yaml.
428
-
* Bad, because apispec doesn't actually run the swagger docs, it just generates them. You would need to use one of the other approaches here in tandem.
425
+
- Good, because the API uses Marshmallow for its data schema, which is a [well-maintained library](https://github.com/marshmallow-code/marshmallow) - it's in the same project.
426
+
- Good, because it gives a lot of flexibility for defining the OpenAPI docs, [including security](https://apispec.readthedocs.io/en/latest/special_topics.html#documenting-security-schemes).
427
+
- Bad, because you still have to specify some of the OpenAPI docs as a comment on the function. The primary gain is being able to use Marshmallow to define the schema models, but the routes are still largely yaml.
428
+
- Bad, because apispec doesn't actually run the swagger docs, it just generates them. You would need to use one of the other approaches here in tandem.
429
429
430
430
### Flask RESTX
431
431
@@ -499,11 +499,11 @@ if __name__ == "__main__":
499
499
```
500
500
</details>
501
501
502
-
* Good, because the way it organizes namespaces (ie. tags), and parameters is intuitive and fairly readable.
503
-
* Good, because it provides implicit [masking logic](https://flask-restx.readthedocs.io/en/latest/mask.html) that makes masking responses easy which is helpful when working with PII.
504
-
* Bad, because while you define a model, you define it as a dictionary, not a class, and thus end up working with just dictionaries. If we wanted any well-structured classes, we'd need to define that separately.
505
-
* Bad, because they have an entire section of documentation about [request parsing](https://flask-restx.readthedocs.io/en/latest/parsing.html) that is deprecated - and seems to have been replaced quite some time ago (not well maintained?).
506
-
* Bad, because the last release was over a year ago, and there have only been a very small number of commits this year.
502
+
- Good, because the way it organizes namespaces (ie. tags), and parameters is intuitive and fairly readable.
503
+
- Good, because it provides implicit [masking logic](https://flask-restx.readthedocs.io/en/latest/mask.html) that makes masking responses easy which is helpful when working with PII.
504
+
- Bad, because while you define a model, you define it as a dictionary, not a class, and thus end up working with just dictionaries. If we wanted any well-structured classes, we'd need to define that separately.
505
+
- Bad, because they have an entire section of documentation about [request parsing](https://flask-restx.readthedocs.io/en/latest/parsing.html) that is deprecated - and seems to have been replaced quite some time ago (not well maintained?).
506
+
- Bad, because the last release was over a year ago, and there have only been a very small number of commits this year.
507
507
508
508
509
509
### APIFairy
@@ -594,9 +594,8 @@ if __name__ == "__main__":
594
594
```
595
595
</details>
596
596
597
-
* Good, because the API uses Marshmallow for its data schema, which is a [well-maintained library](https://github.com/marshmallow-code/marshmallow).
598
-
* Good, because the decorators are named fairly intuitively and help make the methods clearer.
599
-
* Bad, because it insists Marshmallow "just works" but.. doesn't (see the hacky `jsonify` I had to do in the example). The very unhelpful error messages it gave about `jsonify` not existing were very frustrating.
600
-
* Bad, because the documentation doesn't have any fully working examples making it difficult to figure out a minimal viable implementation. It is written as if you're adjusting a fully-formed Marshmallow-based Flask app, and not starting from scratch.
601
-
* Bad, because there doesn't appear to be a ton of support - no questions posted anywhere, and only one article about it.
602
-
597
+
- Good, because the API uses Marshmallow for its data schema, which is a [well-maintained library](https://github.com/marshmallow-code/marshmallow).
598
+
- Good, because the decorators are named fairly intuitively and help make the methods clearer.
599
+
- Bad, because it insists Marshmallow "just works" but.. doesn't (see the hacky `jsonify` I had to do in the example). The very unhelpful error messages it gave about `jsonify` not existing were very frustrating.
600
+
- Bad, because the documentation doesn't have any fully working examples making it difficult to figure out a minimal viable implementation. It is written as if you're adjusting a fully-formed Marshmallow-based Flask app, and not starting from scratch.
601
+
- Bad, because there doesn't appear to be a ton of support - no questions posted anywhere, and only one article about it.
0 commit comments