-
Adonis Core 5.4.2
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Yes, services are a great way to simplify controller logic and a great place to house methods that need to be used across multiple controllers. I typically don't register an IOC namespace for my services, I just import them in the controllers I need them. There are a few ways you can do this. The way you're going about it is great if you need the same instance of the service class to be used for every single request your server receives. If that's not a requirement for you below are some alternatives. Using Static Methods // app/Services/PostService.ts
export default class PostService {
public static async getRecentPosts(numPosts) {
// fetch posts ...
}
}
// app/Controllers/Http/PostsController.ts
import PostService from 'App/Services/PostService'
export default class PostsController {
public async index({ response }: HttpContextContract) {
const posts = await PostService.getRecentPosts()
}
} Note the service method is defined as static, so a new instance of PostService doesn't need to be created in order to be used. Using AdonisJS Fold to Inject the Service Into the Controller Class // app/Services/PostService.ts
export default class PostService {
public async getRecentPosts(numPosts) {
// fetch posts ...
}
}
// app/Controllers/Http/PostsController.ts
import { inject } from '@adonisjs/fold';
import PostService from 'App/Services/PostService'
@inject()
export default class PostsController {
constructor(public postService: PostService) {}
public async index({ response }: HttpContextContract) {
const posts = await this.postService.getRecentPosts()
}
} Here // app/Controllers/Http/PostsController.ts
import PostService from 'App/Services/PostService'
export default class PostsController {
public postService: PostService
constructor() {
this.postService = new PostService()
}
public async index({ response }: HttpContextContract) {
const posts = await this.postService.getRecentPosts()
}
} I'd recommend one of the above usages as they're simpler and easier to understand. However, if you do need one single instance of your service class for all requests in your application, then you'll want to move imports that use the IOC container inside the class instance. The register method inside the provider is where you can register IOC bindings (which would include your service). The IOC container itself isn't ready to be used until the boot method of the provider is called. This is where your error is coming from. The file gets imported, but the IOC container is still registering its bindings. To fix this, instead of importing your Post model at the top level, import it within the class itself. I haven't tried this, you might need to do this within a constructor, but something like this should work: export default class PostService {
public postModel = require('App/Models/Post') // import Post Model inside class
public async getRecentPosts(numPosts) {
// fetch posts ...
}
} |
Beta Was this translation helpful? Give feedback.
Yes, services are a great way to simplify controller logic and a great place to house methods that need to be used across multiple controllers. I typically don't register an IOC namespace for my services, I just import them in the controllers I need them.
There are a few ways you can do this. The way you're going about it is great if you need the same instance of the service class to be used for every single request your server receives. If that's not a requirement for you below are some alternatives.
Using Static Methods