luckymarmot/API-Flow

API-Flow 0.1 Architecture Rework

JonathanMontane opened this issue · 8 comments

The current architecture and models could be strongly improved through a careful refactoring of the app.

Issues

General Issues

Here are some of the current issues that we encounter:

  • no support for multiple bodyTypes
  • no support for multiple contentTypes
  • no support for urlParameters
  • no support for parameter constraints
  • no support for flattening nested groups
  • no support for remote files
  • no support for examples
  • limited support of responses
  • limited support of schemas

Structural issues of the RequestContext object

  • RequestContext.schema was added to solve schema references issues with the Swagger parser
  • RequestContext.environments was added to solve Environment variables issues with the Postman parser

These fields feel like ad-hoc solutions to every format we meet. This is bad design, and we should move away from it. Ultimately, environments variables and schemas are only references that can be resolved locally.

Enhancements

Here are cool things we could integrate:

  • json-schema-faker. A pretty cool library that allows one to generate random json objects that comply with a schema
  • additional authentication method support.
  • improved schema parsing when it's given as a raw string instead of an object

Going Forward

Here is a rough draft of the modification we suggest to make:

  • Rename KeyValue to Parameter model, that will be used for queryParams, urlEncodedParams and formDataParams, and headers.
  • Create a Constraint model that defines under which constraints a Parameter can be used. Each Parameter would therefore have an external list of Constraint under which they can be used/included.
  • Add a Constraint list as an internal field for Parameter, that would describe the constraint the the Parameter itself must respect when being sent.
  • Regroup headers, queryParams, urlEncodedParams, and formDataParams as fields of a ParameterContainer model.
  • Create a Body model, that contains a Constraint list. It should be possible to filter the ParameterContainer based on this Constraint list to generate the actual content of the request.
  • Create a bodies field in Request, that would contain a list of Body.
  • Add description, name and example fields everywhere.
  • Add a flatten method to Group
  • Add a generate method to Parameter, that uses Faker.js or Chance.js to create realistic and compliant data. This would be useful for on the fly example generation.
  • Add name, version, description, and other descriptive fields directly to RequestContext
  • Move all the current exporters in exporters/paw -- changed to serializers/paw
  • Rename Importer files as Exporter -- changed to Serializer
  • Rename Parser files as Importer -- kept as Parser
  • Rename immutables directory as models
  • Rename RequestContext to Core
  • Improve Auth module structure by regrouping all the authentication methods in a single Auth object.
  • Improve Core module structure by grouping the multiple classes intelligently (Didn't look into it yet)
  • Improve Context by removing the schema and environment fields. Create a references field instead that would contain all the references that appear in the model. Maybe use a ReferenceContainer, similar to the ParameterContainer?

TODO issues

Potential Growth

  • CLI

Under this new spec, here is how each of the Core classes would look like:

KeyValue -> renamed Parameter
Parameter:
   - key
   - value
   - type
   - name
   - description
   - example
   - internal: [Constraint]
   - external: [Constraint]
   @ generate

ParameterContainer:
   - headers: [Parameter]
   - queries: [Parameter]
   - body: [Parameter]
   @ getHeaderSet
   @ getUrlParams
   @ getBody

Body:
   - constraints: [Constraint]
   @ filter

Response:
    - code
    - name
    - description
    - example
    - parameters: ParameterContainer
    - bodies: [Body]

Request:
   - id
   - name
   - description
   - url
   - method
   - parameters: ParameterContainer
   - bodies: [Body]
   - auths: [Auth]
   - responses: [Response]
   - timeout

Schema objects would be stored in a Parameter

There is probably some improvements to be done around Environment and EnvironmentReference.
EnvironmentReference should probably be renamed EnvironmentVariable

@mittsh, what's your opinion on these suggestions?

I think most of them make a lot of sense: it's a good thing to do. I think the right names for exporters & importers are serializers & parsers.

Updated Spec:

Constraint:
    - name
    - expression
    @ evaluate

Parameter:
    - key
    - value
    - type
    - name
    - description
    - example
    - internal: [Constraint]
    - external: [Parameter]
    @ generate
    @ validate
    @ isValid

ParameterContainer:
    - headers: [Parameter]
    - queries: [Parameter]
    - body: [Parameter]
    @ getHeaderSet
    @ getUrlParams
    @ getBody
    @ filter

Body:
    - constraints: [Parameter]

Response:
    - code
    - name
    - description
    - example
    - parameters: ParameterContainer
    - bodies: [Body]

Request:
   - id
   - name
   - description
   - url
   - method
   - parameters: ParameterContainer
   - bodies: [Body]
   - auths: [Auth]
   - responses: [Response]
   - timeout

We are using a list of Parameter objects to describe the constraints under which each body can be used, since it is often/always parameter based constraints.

The filter function was moved to the ParameterContainer. It takes as an input a List<Parameter>.

Two functions have been added to Parameter, one for the validation of a Parameter value against the external constraint of another - isValid(parameter) - and one for the validation of a value against the internal constraint of a Parameter - validate(value).

Group.flatten was partially implemented with Group.getRequests, which returns an array containing all the requests of his children and himself.

Group.flatten(depth) could be implemented by traversing the tree to said depth and then using Group.flatten. There are no uses case that requires us to support that at the moment.