Skip to content

Commit

Permalink
Default to using model name for routes
Browse files Browse the repository at this point in the history
  • Loading branch information
twof committed Sep 30, 2018
1 parent c49b21d commit 1a9de8c
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

CrudRouter makes it as simple as possible to set up CRUD (Create, Read, Update, Delete) routes for any `Model`.

## Usage:
## Usage
Within your router setup (`routes.swift` in the default Vapor API template)
```swift
router.crudRegister("todo", for: Todo.self)
router.crudRegister(for: Todo.self)
```
That's it!

Expand All @@ -19,6 +19,37 @@ PUT /todo/:id
DELETE /todo/:id
```

Generated paths default to using lower snake case so for example, if you were to do

```swift
router.crudRegister(for: SchoolTeacher.self)
```
you'd get routes like

```
GET /school_teacher
GET /school_teacher/:id
POST /school_teacher
PUT /school_teacher/:id
DELETE /school_teacher/:id
```

#### Path Configuration
If you'd like to supply your own path rather than using the name of the supplied model, you can also do that

```swift
router.crudRegister("account", for: User.self)
```
results in

```
GET /account
GET /account/:id
POST /account
PUT /account/:id
DELETE /account/:id
```

### Future features
- query parameter support
- PATCH support
Expand Down
30 changes: 26 additions & 4 deletions Sources/CrudRouter/CrudRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,41 @@ fileprivate extension CrudControllerProtocol {

fileprivate final class CrudController<T: Model>: CrudControllerProtocol where T.ID: Parameter, T: Content {
typealias ModelType = T


}
extension String {
func snakeCased() -> String? {
let pattern = "([a-z0-9])([A-Z])"

let regex = try? NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(location: 0, length: self.count)
return regex?.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: "$1_$2").lowercased()
}
}


public extension Router {
func crudRegister<ModelType: Model & Content>(
_ path: PathComponentsRepresentable...,
for type: ModelType.Type
) where ModelType.ID: Parameter {
) where ModelType.ID: Parameter {
let controller = CrudController<ModelType>()

self.get(path, CrudController<ModelType>.ModelType.ID.parameter, use: controller.index)
let path
= path.count == 0
? [String(describing: ModelType.self).snakeCased()! as PathComponentsRepresentable]
: path

self.get(path, ModelType.ID.parameter, use: controller.index)
self.get(path, use: controller.indexAll)
self.post(path, use: controller.create)
self.put(path, CrudController<ModelType>.ModelType.ID.parameter, use: controller.update)
self.delete(path, CrudController<ModelType>.ModelType.ID.parameter, use: controller.delete)
self.put(path, ModelType.ID.parameter, use: controller.update)
self.delete(path, ModelType.ID.parameter, use: controller.delete)
}

// notes:
// we want to register other models
// if something like /todo/1/user comes in, it ought to be translated to
// /todo?userid=1
}

0 comments on commit 1a9de8c

Please sign in to comment.