Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.3.0 discussion #48

Closed
danielsz opened this issue Jan 11, 2016 · 15 comments
Closed

0.3.0 discussion #48

danielsz opened this issue Jan 11, 2016 · 15 comments

Comments

@danielsz
Copy link
Owner

This is meant to be the discussion for the upcoming changes. Version 0.3.0 of system will incorporate the Duct abstractions: https://github.com/weavejester/duct/wiki/Components
This will be a breaking release for users who were leveraging the app component.

A snapshot release with the proposed changes is available on Clojars.
The example projects have been updated to demonstrate usage.
Additionally, there is a new example demonstrating usage with multiple endpoints:
https://github.com/danielsz/system-duct-style-example
I welcome all comments/criticism/contributions.

@yenda
Copy link

yenda commented Jan 13, 2016

Great news ! This will make it easier for anyone who wants to organize his code with components and a webapp.

I was hoping that the duct.components and system.components will merge someday and share the effort, is it going to be the case ?

@danielsz
Copy link
Owner Author

Yes, @yenda, the Duct components show us a way to wire a web application based on solid principles.

There are some subtle differences in the signature apis of both, but that should not distract you from the fact that they are essentially the same.

System adapted the Duct components to fit with the rest of its parts. There is no ongoing development or shared effort in the usual sense. It's idea sharing and cross-fertilization at play here.

@danielsz
Copy link
Owner Author

Fresh from the oven: a new middleware component.

Duct processes middleware in the handler component for internal reasons. We don't need to follow this. In system, we can componentize middleware as well, and I personally like the consistency to have an endpoint, a middleware and a handler component.

The example has been updated to show usage.

@yenda
Copy link

yenda commented Jan 18, 2016

Looks like it works fine after updating my system.clj accordingly. I was surprised that my app broke there in the first place without me updating anything, looks like you didn't change the version and boot downloaded the update automatically from clojars.

Retrieving system-0.3.0-20160117.105632-3.jar from https://clojars.org/repo/

...   

Wrong number of args (1) passed to: handler/new-handler

It is a nice update anyway, cleaner.

@danielsz
Copy link
Owner Author

I'm happy to hear, @yenda.

Yes, that is how snapshot releases work. They always update themselves to the latest snapshot available. Both in Leiningen and in Boot. A standard release is stable, a snapshot is inherently not, but that is by design. It fits the scenario when a maintainer is not yet ready to issue a release, but wants to share ongoing development.

@danielsz
Copy link
Owner Author

I'm in the process of revising the namespace reloading mechanism in the system task. It leverages tools.namespace directly now. Options might change. That is another upcoming breaking change with 0.3.0. A snapshot will be uploaded after some more testing.

@danielsz
Copy link
Owner Author

system 0.3.0 has been released.

@arichiardi
Copy link

👍

@prepor
Copy link

prepor commented Dec 14, 2016

Hello! How about some documentation about how middleware / handler / endpoints should be used?

(new-middleware {:middleware [[wrap-not-found :not-found]
                                             [wrap-restful-format]
                                             [wrap-defaults :defaults]]
                                :defaults api-defaults
                                :not-found  "<h2>The requested page does not exist.</h2>"} )

Is not really self-documented and currently, the only way to work with it is read the code.

@prepor
Copy link

prepor commented Dec 14, 2016

For example, what is the point of this syntax for middleware? Why not just:

(new-middleware {:middleware [[wrap-not-found "<h2>The requested page does not exist.</h2>"]
                              [wrap-restful-format]
                              [wrap-defaults api-defaults]]} )

In both cases you can't inject component to middleware (Duct also has this problem). Duct designed it for its edn declarations (with `:replace stuff). What is reason for this here?

@danielsz
Copy link
Owner Author

danielsz commented Dec 14, 2016

Your point about middleware is correct: you can't inject into middleware component, and the configuration of the middleware can be simplified in the way you showed. It's a relic of when it was ported from Duct. This will be addressed in time.

You are also correct that system has no proper documentation. I plan to tackle this eventually, but it will need planning. Maybe spec can be useful here.

The Duct abstractions in system 0.3.2 are being enhanced. Now you can inject named middleware components into endpoint components, and the framework will handle the Compojure routes transparently. This allows to import arbitrary endpoints across namespaces (libraries) even if they depend on different middleware. The code is already in SNAPSHOT, and I'm writing a blog post that will go into detail, explaining the design.
To see this in action, please refer to the websockets example (in the examples directory).

@danielsz
Copy link
Owner Author

Deployed [org.danielsz/system "0.3.2-SNAPSHOT"] with simplified middleware component, like suggested above (thank you, @prepor!)

The middleware now receives a vector of functions or vectors to be composed. If vector is specified, will return a function that applies the first item in vector to the handler and the rest of vector items (middleware arguments). If sole function is specified, return as is. Examples have been updated. This is a breaking change.

Comments/suggestions welcome.

@danielsz danielsz reopened this Dec 14, 2016
danielsz added a commit that referenced this issue Jan 3, 2017
- Middleware plays now in the dependency injection mechanism
- You can wrap the component with middleware
- @prepor's comment #48
@danielsz
Copy link
Owner Author

danielsz commented Jan 3, 2017

As of latest snapshot, you can now inject component in middleware.

:middleware (component/using (new-middleware {:middleware [wrap-restful-format 
                                                          [wrap-login :component]]})
                              [:db])

The convention is to use :component in the middleware vector to indicate that the middleware takes the component as argument.
And now your middleware can look like this:

(defn wrap-login [handler {db :db}]
  (fn [{session :session headers :headers :as request}]
    (if (:uid session)
      (handler request)
      (if-let [screen-name (get-in session [:twitter :screen_name])]
          (do
            (save db screen-name) ; for example
            (handler (assoc request :session (assoc session :uid screen-name))))
          (handler request)))))

Thank you, @prepor.

@danielsz
Copy link
Owner Author

FYI @prepor Docstrings have been added to the handler component and the middleware component.

@danielsz
Copy link
Owner Author

Stable version released with all issues in this thread addressed. Documentation efforts are ongoing. Closing this for now.

featheredtoast added a commit to featheredtoast/chestnut that referenced this issue Feb 17, 2017
VenusPR added a commit to VenusPR/System_development that referenced this issue Mar 12, 2023
- Middleware plays now in the dependency injection mechanism
- You can wrap the component with middleware
- @prepor's comment danielsz/system#48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants